1
00:00:00,060 --> 00:00:04,440
okay let's get started hope everyone had

2
00:00:03,659 --> 00:00:07,170
a good weekend

3
00:00:04,440 --> 00:00:09,990
so this this week we're gonna do all

4
00:00:07,170 --> 00:00:12,000
stuff about server security we talked a

5
00:00:09,990 --> 00:00:13,099
little bit about sequel and actually

6
00:00:12,000 --> 00:00:16,529
talked a lot about sequel injection

7
00:00:13,099 --> 00:00:21,359
before and and we also talked a little

8
00:00:16,529 --> 00:00:23,609
bit about how to handle users who are

9
00:00:21,359 --> 00:00:25,350
maybe yet hitting your site too

10
00:00:23,609 --> 00:00:26,910
frequently and trying to log in too many

11
00:00:25,350 --> 00:00:28,140
times and have to deal with the rate

12
00:00:26,910 --> 00:00:31,980
limiting and CAPTCHAs and stuff like

13
00:00:28,140 --> 00:00:33,780
that and so today is gonna be sort of an

14
00:00:31,980 --> 00:00:35,250
extension of that just more kinds of

15
00:00:33,780 --> 00:00:36,899
ways you can mess up on the server

16
00:00:35,250 --> 00:00:39,600
different kinds of attacks and things

17
00:00:36,899 --> 00:00:43,230
you can do to defend against attackers

18
00:00:39,600 --> 00:00:47,129
and mostly focused on safe coding

19
00:00:43,230 --> 00:00:49,530
practices so things that things that you

20
00:00:47,129 --> 00:00:51,750
might be doing wrong that will encourage

21
00:00:49,530 --> 00:00:59,329
sort of security issues that you know to

22
00:00:51,750 --> 00:01:01,590
come up uh or stuff like that basically

23
00:00:59,329 --> 00:01:04,769
yeah so let's get started so first in

24
00:01:01,590 --> 00:01:06,720
admin so there's gonna be a hands-on

25
00:01:04,769 --> 00:01:08,340
workshop with Pete Snyder from brave

26
00:01:06,720 --> 00:01:10,710
who's our first guest lecture if you

27
00:01:08,340 --> 00:01:13,470
remember and the Stanford Applied

28
00:01:10,710 --> 00:01:15,780
cybersecurity Club is going to be

29
00:01:13,470 --> 00:01:17,520
hosting that and that's gonna be you

30
00:01:15,780 --> 00:01:20,369
guessed Thursday it's 6 to 7 in gates

31
00:01:17,520 --> 00:01:22,290
174 and dinner's served right yeah also

32
00:01:20,369 --> 00:01:24,299
we have some new students in class today

33
00:01:22,290 --> 00:01:26,280
in the very back the two people in the

34
00:01:24,299 --> 00:01:27,500
very back are some new students my

35
00:01:26,280 --> 00:01:29,549
parents

36
00:01:27,500 --> 00:01:32,009
they're here they were in town they're

37
00:01:29,549 --> 00:01:33,920
here to watch the watch me lecture so be

38
00:01:32,009 --> 00:01:36,659
nice to them

39
00:01:33,920 --> 00:01:38,040
cool all right so I also want to mention

40
00:01:36,659 --> 00:01:39,780
there have been three students so far

41
00:01:38,040 --> 00:01:42,000
who have found security issues and

42
00:01:39,780 --> 00:01:43,710
reported them and so they've received

43
00:01:42,000 --> 00:01:44,790
extra credit I just wanted to call out a

44
00:01:43,710 --> 00:01:47,180
couple of them that were kind of

45
00:01:44,790 --> 00:01:50,520
interesting there was an XSS found in

46
00:01:47,180 --> 00:01:53,009
access and since access is part of the

47
00:01:50,520 --> 00:01:54,509
Stanford bug bounty program this student

48
00:01:53,009 --> 00:01:55,799
I don't know if I want to say who was it

49
00:01:54,509 --> 00:01:58,140
can you volunteer your own name if you

50
00:01:55,799 --> 00:02:00,270
want to but anyway was was able to

51
00:01:58,140 --> 00:02:02,670
report the bug to the bug bounty program

52
00:02:00,270 --> 00:02:05,009
and was given a hundred dollars for that

53
00:02:02,670 --> 00:02:07,590
from Stanford which is pretty cool and

54
00:02:05,009 --> 00:02:11,370
another student found an XSS in a CS

55
00:02:07,590 --> 00:02:13,110
course website and actually led to

56
00:02:11,370 --> 00:02:13,830
potentially be able to change assignment

57
00:02:13,110 --> 00:02:18,000
scores

58
00:02:13,830 --> 00:02:21,240
which is not definitely not good

59
00:02:18,000 --> 00:02:22,950
and then lastly someone else found an

60
00:02:21,240 --> 00:02:24,510
insecure design that allowed the test

61
00:02:22,950 --> 00:02:25,920
cases in a coding challenge for a job

62
00:02:24,510 --> 00:02:27,060
interview to be revealed so you can sort

63
00:02:25,920 --> 00:02:30,060
of see the test cases they were gonna

64
00:02:27,060 --> 00:02:31,500
test your code against the latter ones

65
00:02:30,060 --> 00:02:33,510
didn't receive any kind of a bug bounty

66
00:02:31,500 --> 00:02:35,640
reward because they weren't covered by

67
00:02:33,510 --> 00:02:37,290
as far as far as I'm concerned or aware

68
00:02:35,640 --> 00:02:40,020
the CS course sites aren't covered by

69
00:02:37,290 --> 00:02:41,670
the bug bounty program but maybe the

70
00:02:40,020 --> 00:02:42,150
coding challenge one will get get a

71
00:02:41,670 --> 00:02:44,160
reward

72
00:02:42,150 --> 00:02:45,390
yeah just a reminder about this you have

73
00:02:44,160 --> 00:02:47,490
a couple weeks left if you're interested

74
00:02:45,390 --> 00:02:50,430
I was completely optional but it's kind

75
00:02:47,490 --> 00:02:53,700
of fun so remember you can do this if

76
00:02:50,430 --> 00:02:58,160
you want cool

77
00:02:53,700 --> 00:03:01,470
so so first let's start with a story so

78
00:02:58,160 --> 00:03:04,680
one we were trick to make 25k security

79
00:03:01,470 --> 00:03:06,900
teams hey toon there's there's a story a

80
00:03:04,680 --> 00:03:09,780
couple weeks ago on on all the tech news

81
00:03:06,900 --> 00:03:10,770
sites that's super relevant for the the

82
00:03:09,780 --> 00:03:12,330
stuff we're gonna be talking about today

83
00:03:10,770 --> 00:03:14,000
so I thought I'd just go through what

84
00:03:12,330 --> 00:03:16,080
this security researcher was able to do

85
00:03:14,000 --> 00:03:19,230
so this is the title of the post

86
00:03:16,080 --> 00:03:22,740
bypassing github so auth flow and what

87
00:03:19,230 --> 00:03:25,050
this person was able to do was basically

88
00:03:22,740 --> 00:03:28,440
they can make a github application which

89
00:03:25,050 --> 00:03:29,940
is able to read a user's github data and

90
00:03:28,440 --> 00:03:31,320
typically there's a there's a prompt

91
00:03:29,940 --> 00:03:33,720
that says do you want it you know do you

92
00:03:31,320 --> 00:03:35,610
agree to to give this application access

93
00:03:33,720 --> 00:03:36,930
to your data and the the user is

94
00:03:35,610 --> 00:03:39,420
supposed to supposed to click this

95
00:03:36,930 --> 00:03:40,320
button saying that they know what what

96
00:03:39,420 --> 00:03:42,150
the permissions are that this

97
00:03:40,320 --> 00:03:44,840
application wants and to give their

98
00:03:42,150 --> 00:03:47,610
consent he was able to find a way to

99
00:03:44,840 --> 00:03:50,670
without any user interaction at all to

100
00:03:47,610 --> 00:03:52,920
send a request to github with the users

101
00:03:50,670 --> 00:03:55,110
cookies attached that granted his

102
00:03:52,920 --> 00:03:57,150
application any permissions he wants it

103
00:03:55,110 --> 00:04:00,060
on the user's github account so just by

104
00:03:57,150 --> 00:04:01,320
visiting this attackers site your entire

105
00:04:00,060 --> 00:04:03,300
github account is just completely owned

106
00:04:01,320 --> 00:04:05,130
and the attacker can access all of the

107
00:04:03,300 --> 00:04:08,160
data all of the private repositories all

108
00:04:05,130 --> 00:04:09,360
the company secrets everything and this

109
00:04:08,160 --> 00:04:11,970
is the highest bounty that github is

110
00:04:09,360 --> 00:04:14,460
ever paid out to anybody so it's pretty

111
00:04:11,970 --> 00:04:17,130
bad really bad it also affected all of

112
00:04:14,460 --> 00:04:18,570
the enterprise github deployments which

113
00:04:17,130 --> 00:04:21,350
are used you know but by companies

114
00:04:18,570 --> 00:04:23,970
internally for it for super secret code

115
00:04:21,350 --> 00:04:25,500
the cool thing is we know pretty much

116
00:04:23,970 --> 00:04:27,600
from the stuff we learned in this class

117
00:04:25,500 --> 00:04:29,640
so far any one of you

118
00:04:27,600 --> 00:04:30,840
found this bug like it's really there

119
00:04:29,640 --> 00:04:32,310
just a couple of extra things I'm gonna

120
00:04:30,840 --> 00:04:35,130
explain for you to get the whole picture

121
00:04:32,310 --> 00:04:36,300
but this is the kind of stuff that you

122
00:04:35,130 --> 00:04:38,550
could do if you wanted to

123
00:04:36,300 --> 00:04:40,500
some people do just spend full time

124
00:04:38,550 --> 00:04:43,110
looking for bugs and and and make a

125
00:04:40,500 --> 00:04:44,610
living from just finding bugs that's

126
00:04:43,110 --> 00:04:47,670
actually how this person found this bug

127
00:04:44,610 --> 00:04:50,010
was he decided he was curious could I

128
00:04:47,670 --> 00:04:51,630
make a living just looking for bugs and

129
00:04:50,010 --> 00:04:53,850
so he decided to spend I think was

130
00:04:51,630 --> 00:04:55,740
either a week or a month just looking

131
00:04:53,850 --> 00:04:59,550
for bugs and github and this was the

132
00:04:55,740 --> 00:05:00,870
result of that so you know um his first

133
00:04:59,550 --> 00:05:03,230
his first time trying to do such a thing

134
00:05:00,870 --> 00:05:06,140
so so it's pretty cool I think I think

135
00:05:03,230 --> 00:05:08,580
yeah I think it's an inspiring story

136
00:05:06,140 --> 00:05:10,830
because let's before we go into how it

137
00:05:08,580 --> 00:05:13,500
works let's recall a cross-site request

138
00:05:10,830 --> 00:05:14,280
forgery so hopefully everyone remembers

139
00:05:13,500 --> 00:05:15,990
this

140
00:05:14,280 --> 00:05:18,660
so cross-site request forgery the idea

141
00:05:15,990 --> 00:05:20,700
is this is an attack where an attacker

142
00:05:18,660 --> 00:05:22,950
can force a user to execute actions

143
00:05:20,700 --> 00:05:24,630
against a web app that they happen to be

144
00:05:22,950 --> 00:05:26,940
currently authenticated with or logged

145
00:05:24,630 --> 00:05:29,580
into so the way that attacker does this

146
00:05:26,940 --> 00:05:31,470
is well the authentication mechanism

147
00:05:29,580 --> 00:05:34,470
that the browser uses is cookies and

148
00:05:31,470 --> 00:05:36,360
cookies have this what we call ambient

149
00:05:34,470 --> 00:05:39,560
Authority model who remembers ambient

150
00:05:36,360 --> 00:05:47,760
Authority somebody want to remind us

151
00:05:39,560 --> 00:05:53,330
what's ambient Authority again come on

152
00:05:47,760 --> 00:06:03,240
this is sad okay all right that's fine

153
00:05:53,330 --> 00:06:05,280
did you give it a shot yeah yeah it's a

154
00:06:03,240 --> 00:06:06,660
fancy word for basically once you have

155
00:06:05,280 --> 00:06:08,130
this authority that you've gained by

156
00:06:06,660 --> 00:06:10,260
logging in and proving yourself to the

157
00:06:08,130 --> 00:06:12,150
site that you're logging into all future

158
00:06:10,260 --> 00:06:14,040
requests to that site automatically have

159
00:06:12,150 --> 00:06:15,750
that authority that you proved once at

160
00:06:14,040 --> 00:06:17,100
the beginning by logging in so all

161
00:06:15,750 --> 00:06:18,510
future requests have that same authority

162
00:06:17,100 --> 00:06:19,890
as that user and that's because the

163
00:06:18,510 --> 00:06:21,420
cookies are attached automatically to

164
00:06:19,890 --> 00:06:22,290
those requests by the browser this is

165
00:06:21,420 --> 00:06:25,850
the same thing we've been talking about

166
00:06:22,290 --> 00:06:27,660
all quarters just a fancy phrase for it

167
00:06:25,850 --> 00:06:29,790
okay so what does this mean this means

168
00:06:27,660 --> 00:06:32,580
that if the if attacker comm is able to

169
00:06:29,790 --> 00:06:34,830
cause an HTTP request to get sent to

170
00:06:32,580 --> 00:06:36,479
victim comm then the browser

171
00:06:34,830 --> 00:06:41,960
automatically attaches the victim comm

172
00:06:36,479 --> 00:06:43,030
cookies to this request right so I

173
00:06:41,960 --> 00:06:45,080
don't think I ever showed a picture

174
00:06:43,030 --> 00:06:46,580
pictorial version of how this attack

175
00:06:45,080 --> 00:06:48,770
works so I went ahead and whipped one of

176
00:06:46,580 --> 00:06:50,569
those up just to review so we have the

177
00:06:48,770 --> 00:06:52,910
client in the server this is the the

178
00:06:50,569 --> 00:06:56,300
victim server here and the way CSRF

179
00:06:52,910 --> 00:06:59,150
works is the user visits the site and

180
00:06:56,300 --> 00:07:00,620
decides to login so a login request is

181
00:06:59,150 --> 00:07:02,800
sent you can see there there's a

182
00:07:00,620 --> 00:07:05,690
username and a password in that request

183
00:07:02,800 --> 00:07:07,849
and then the server checks whether the

184
00:07:05,690 --> 00:07:09,830
username and password is valid let's

185
00:07:07,849 --> 00:07:12,530
assume that it is and so the server will

186
00:07:09,830 --> 00:07:14,930
send back a response and this response

187
00:07:12,530 --> 00:07:16,910
contains a set cookie header that sets a

188
00:07:14,930 --> 00:07:18,590
cookie session ID equals one two three

189
00:07:16,910 --> 00:07:21,500
four and tells the user you log in you

190
00:07:18,590 --> 00:07:23,810
logged in successfully now some time

191
00:07:21,500 --> 00:07:26,630
passes the browser is holding on to this

192
00:07:23,810 --> 00:07:28,160
cookie and so maybe a day goes by or

193
00:07:26,630 --> 00:07:29,900
maybe the user opens another tab while

194
00:07:28,160 --> 00:07:33,470
they're while they're still logged into

195
00:07:29,900 --> 00:07:34,580
the site or something like this and now

196
00:07:33,470 --> 00:07:35,900
they happen to get sent a link to an

197
00:07:34,580 --> 00:07:38,509
attackers web site so they go to that

198
00:07:35,900 --> 00:07:40,639
site they make a request the attackers

199
00:07:38,509 --> 00:07:42,740
site so my HTML gets sent back and

200
00:07:40,639 --> 00:07:44,720
inside this HTML is whatever JavaScript

201
00:07:42,740 --> 00:07:47,419
the attacker wants to include and so

202
00:07:44,720 --> 00:07:49,849
once that page loads that page is going

203
00:07:47,419 --> 00:07:52,509
to send a request not to back to the

204
00:07:49,849 --> 00:07:55,430
attacker server but to the victim server

205
00:07:52,509 --> 00:07:57,590
and this request is going to be to some

206
00:07:55,430 --> 00:08:00,199
sensitive endpoint like safe to transfer

207
00:07:57,590 --> 00:08:01,370
money and they're going to include the

208
00:08:00,199 --> 00:08:04,159
parameters that they happen to know that

209
00:08:01,370 --> 00:08:06,949
this endpoint is expecting so $100 and

210
00:08:04,159 --> 00:08:10,070
let's send it to Malory and the browser

211
00:08:06,949 --> 00:08:13,310
helpfully attaches the cookie header to

212
00:08:10,070 --> 00:08:14,870
that and then the server as far as the

213
00:08:13,310 --> 00:08:17,000
server is concerned it looks like this

214
00:08:14,870 --> 00:08:18,289
came from from a legitimate forum

215
00:08:17,000 --> 00:08:20,210
because all it can see is this request

216
00:08:18,289 --> 00:08:23,030
and everything checks out in that

217
00:08:20,210 --> 00:08:27,949
request so hopefully this is review and

218
00:08:23,030 --> 00:08:30,409
any questions about this this is sort of

219
00:08:27,949 --> 00:08:32,899
standard CSRF okay cool

220
00:08:30,409 --> 00:08:35,029
okay so recall the way we fix this is

221
00:08:32,899 --> 00:08:37,849
same site cookies so same site cookies

222
00:08:35,029 --> 00:08:39,740
allow you to say I only want my cookies

223
00:08:37,849 --> 00:08:42,950
to be attached when the request is

224
00:08:39,740 --> 00:08:44,870
initiated by my own site so if the

225
00:08:42,950 --> 00:08:46,670
request is coming from victim comm to

226
00:08:44,870 --> 00:08:49,279
victim comm then the browser will

227
00:08:46,670 --> 00:08:50,900
include the cookie header but if the

228
00:08:49,279 --> 00:08:52,279
request is coming from attacker com to

229
00:08:50,900 --> 00:08:55,130
victim comp then the browser doesn't

230
00:08:52,279 --> 00:08:55,920
include the cookie header so you'll see

231
00:08:55,130 --> 00:08:57,959
the same site comes

232
00:08:55,920 --> 00:09:02,279
all the time it's a really great cookie

233
00:08:57,959 --> 00:09:03,510
feature okay so now let's talk about a

234
00:09:02,279 --> 00:09:05,130
new thing we haven't talked about before

235
00:09:03,510 --> 00:09:07,680
and I actually wasn't planning to

236
00:09:05,130 --> 00:09:08,910
discuss this at all in this class but

237
00:09:07,680 --> 00:09:10,410
I'm gonna mention it here because it's

238
00:09:08,910 --> 00:09:13,110
it's a requirement to understand the

239
00:09:10,410 --> 00:09:16,949
attack that that this this attacker

240
00:09:13,110 --> 00:09:17,760
found in in github so so the reason why

241
00:09:16,949 --> 00:09:19,380
I wasn't gonna bring it up is because

242
00:09:17,760 --> 00:09:23,449
CSRF tokens are actually kind of

243
00:09:19,380 --> 00:09:25,350
unnecessary these days they are a way to

244
00:09:23,449 --> 00:09:28,320
effectively get the behavior that we get

245
00:09:25,350 --> 00:09:30,269
from same site cookies but but before

246
00:09:28,320 --> 00:09:31,500
same site cookies were thing before

247
00:09:30,269 --> 00:09:34,709
browsers actually supported this whole

248
00:09:31,500 --> 00:09:36,600
concept so one thing we might ask is

249
00:09:34,709 --> 00:09:39,180
what if what what did web sites used to

250
00:09:36,600 --> 00:09:42,329
do before the same site cookie attribute

251
00:09:39,180 --> 00:09:44,010
existed I guess for a long time for for

252
00:09:42,329 --> 00:09:45,149
probably the majority of the web's

253
00:09:44,010 --> 00:09:47,040
existence because the same cycle he's

254
00:09:45,149 --> 00:09:48,449
actually a really new feature for the

255
00:09:47,040 --> 00:09:49,709
majority the web's existence there was

256
00:09:48,449 --> 00:09:52,680
no way to say that you wanted your

257
00:09:49,709 --> 00:09:54,329
cookie to be same site so that meet what

258
00:09:52,680 --> 00:09:55,709
does that mean that means that basically

259
00:09:54,329 --> 00:09:57,540
it was possible for most of the web's

260
00:09:55,709 --> 00:09:59,160
existence that attacker com could send a

261
00:09:57,540 --> 00:10:00,959
get or a post request to your site

262
00:09:59,160 --> 00:10:04,860
victim comm and your cookies would be

263
00:10:00,959 --> 00:10:06,060
attached so the browser allowed this and

264
00:10:04,860 --> 00:10:10,589
sites had no way to opt-out of his

265
00:10:06,060 --> 00:10:12,329
behavior and yet we need some way to

266
00:10:10,589 --> 00:10:14,040
prevent any sent any random site from

267
00:10:12,329 --> 00:10:15,690
from being able to submit forms to our

268
00:10:14,040 --> 00:10:21,120
server with cookies attached so what did

269
00:10:15,690 --> 00:10:24,750
sites do any ideas anyone if you already

270
00:10:21,120 --> 00:10:28,620
notice the S or F token is okay yeah I

271
00:10:24,750 --> 00:10:31,620
know you know anyone have any ideas of

272
00:10:28,620 --> 00:10:33,180
how how we could detect how we could

273
00:10:31,620 --> 00:10:35,880
differentiate whether a request is

274
00:10:33,180 --> 00:10:45,120
coming from from our site or from from

275
00:10:35,880 --> 00:10:46,740
an attackers site yeah look

276
00:10:45,120 --> 00:10:49,050
so you could look at the referer header

277
00:10:46,740 --> 00:10:51,120
will so give you some idea that's right

278
00:10:49,050 --> 00:10:52,290
not perfect for some of the reasons we

279
00:10:51,120 --> 00:10:53,910
talked about in that and that lecture

280
00:10:52,290 --> 00:10:54,990
about refers we're sort of there's some

281
00:10:53,910 --> 00:10:56,970
ways that the attacker can kind of

282
00:10:54,990 --> 00:10:59,189
disable the referer header but it is it

283
00:10:56,970 --> 00:11:00,660
is something yeah there's really

284
00:10:59,189 --> 00:11:02,939
originally no good way no you know

285
00:11:00,660 --> 00:11:04,589
built-in mechanism in the browser or in

286
00:11:02,939 --> 00:11:06,300
any web standards to enable a site to

287
00:11:04,589 --> 00:11:08,519
say they wanted their cookies to behave

288
00:11:06,300 --> 00:11:10,139
in the same site way until that spec was

289
00:11:08,519 --> 00:11:13,259
created until browsers implemented it

290
00:11:10,139 --> 00:11:14,670
and so so the answer to how we how how

291
00:11:13,259 --> 00:11:15,839
we solved this problem is that every

292
00:11:14,670 --> 00:11:18,959
single site had to implement this thing

293
00:11:15,839 --> 00:11:23,279
called CSRF tokens so let's talk about

294
00:11:18,959 --> 00:11:26,220
how that works so basically a CSRF token

295
00:11:23,279 --> 00:11:28,019
is a nonce and remember a nonce is just

296
00:11:26,220 --> 00:11:29,790
some secret unpredictable value

297
00:11:28,019 --> 00:11:32,550
generated by the server and transmitted

298
00:11:29,790 --> 00:11:35,249
to the client and the way we use this

299
00:11:32,550 --> 00:11:38,100
ERF token is that the client must

300
00:11:35,249 --> 00:11:39,839
include the CSRF token in all subsequent

301
00:11:38,100 --> 00:11:42,059
HTTP requests that they make to the

302
00:11:39,839 --> 00:11:45,480
server in order for the server to

303
00:11:42,059 --> 00:11:46,769
recognize that as a valid request so if

304
00:11:45,480 --> 00:11:48,420
you send a request to the server and you

305
00:11:46,769 --> 00:11:52,350
don't include the CSRF token the

306
00:11:48,420 --> 00:11:54,569
server's gonna say this is an invalid

307
00:11:52,350 --> 00:11:55,769
request if the token is missing or if

308
00:11:54,569 --> 00:11:58,139
it's wrong it's gonna be an invalid

309
00:11:55,769 --> 00:11:59,790
request so it's basically some some some

310
00:11:58,139 --> 00:12:01,709
the server's gonna give some value to

311
00:11:59,790 --> 00:12:02,819
the client and say all your requests

312
00:12:01,709 --> 00:12:04,620
that you send in the future must include

313
00:12:02,819 --> 00:12:07,519
that value or I'm gonna I'm gonna reject

314
00:12:04,620 --> 00:12:11,339
them ok so far so good

315
00:12:07,519 --> 00:12:13,290
ok so this is how you typically include

316
00:12:11,339 --> 00:12:15,870
a token so you you would include an

317
00:12:13,290 --> 00:12:17,249
input element in your page and there's a

318
00:12:15,870 --> 00:12:19,259
type hidden' which is kind of cool so

319
00:12:17,249 --> 00:12:22,050
you can include a hidden form element in

320
00:12:19,259 --> 00:12:23,790
a form and let's give it the name CSRF

321
00:12:22,050 --> 00:12:26,730
token and give it the value of the of

322
00:12:23,790 --> 00:12:28,949
the actual token and so because this is

323
00:12:26,730 --> 00:12:29,490
an input field when our form is

324
00:12:28,949 --> 00:12:32,009
submitted

325
00:12:29,490 --> 00:12:34,679
all the inputs get sent to the server as

326
00:12:32,009 --> 00:12:36,449
part of the form and this is going to

327
00:12:34,679 --> 00:12:38,429
get included as one of the of the form

328
00:12:36,449 --> 00:12:40,499
fields it's as if the user had typed

329
00:12:38,429 --> 00:12:41,759
this into a form field but of course

330
00:12:40,499 --> 00:12:45,029
they don't have to do that because it's

331
00:12:41,759 --> 00:12:46,679
gonna be included automatically for them

332
00:12:45,029 --> 00:12:49,980
and so how does the server actually

333
00:12:46,679 --> 00:12:51,449
generate these tokens so there's two

334
00:12:49,980 --> 00:12:52,889
approaches you might use one is you can

335
00:12:51,449 --> 00:12:56,490
just sort of randomly pick up pick a

336
00:12:52,889 --> 00:12:58,830
value a nonce and so you know pick it

337
00:12:56,490 --> 00:13:00,870
randomly turn it into a string and then

338
00:12:58,830 --> 00:13:03,090
to use that as the value or you could

339
00:13:00,870 --> 00:13:04,650
generate it based off of some

340
00:13:03,090 --> 00:13:09,690
information in the request itself like

341
00:13:04,650 --> 00:13:14,190
the session ID okay so now we have this

342
00:13:09,690 --> 00:13:15,600
token the question is how do we use it

343
00:13:14,190 --> 00:13:19,800
what does it actually give us how does

344
00:13:15,600 --> 00:13:21,090
it actually protect us against CSRF so

345
00:13:19,800 --> 00:13:21,890
let's look at how that how CSRF token

346
00:13:21,090 --> 00:13:26,100
works

347
00:13:21,890 --> 00:13:27,900
this should hopefully make it clearer so

348
00:13:26,100 --> 00:13:31,110
we have a client they show up to our

349
00:13:27,900 --> 00:13:33,270
server and this is similar to before so

350
00:13:31,110 --> 00:13:35,790
they're gonna send a login request with

351
00:13:33,270 --> 00:13:37,950
a username and a password the server

352
00:13:35,790 --> 00:13:41,430
checks that it's valid let's assume it's

353
00:13:37,950 --> 00:13:43,560
valid so the server sends back this is

354
00:13:41,430 --> 00:13:45,540
very similar to before it sends back a

355
00:13:43,560 --> 00:13:48,000
set cookie header giving the user a

356
00:13:45,540 --> 00:13:50,340
session and it tells them that login was

357
00:13:48,000 --> 00:13:54,240
successful but you'll notice that also

358
00:13:50,340 --> 00:13:56,280
included here an extra bit of HTML which

359
00:13:54,240 --> 00:13:57,750
is the CSRF token that it chose for the

360
00:13:56,280 --> 00:14:00,300
user in this case we chose a really

361
00:13:57,750 --> 00:14:03,750
insecure one ABC but I need to save

362
00:14:00,300 --> 00:14:06,330
space on my slides so so so now that

363
00:14:03,750 --> 00:14:07,980
this page includes this token and so

364
00:14:06,330 --> 00:14:10,110
what's gonna happen is if the client

365
00:14:07,980 --> 00:14:12,750
interacts in any way with the page that

366
00:14:10,110 --> 00:14:14,010
was sent back let's say it submits

367
00:14:12,750 --> 00:14:16,140
another form now to do a bank transfer

368
00:14:14,010 --> 00:14:19,590
write this token is going to be included

369
00:14:16,140 --> 00:14:21,990
in that request right so so sometime

370
00:14:19,590 --> 00:14:24,390
later the client decides to actually

371
00:14:21,990 --> 00:14:25,920
submit a transfer and so you'll see here

372
00:14:24,390 --> 00:14:27,870
that the browser attached that attach

373
00:14:25,920 --> 00:14:29,970
the cookie like usual and then we have

374
00:14:27,870 --> 00:14:33,180
the same form fields as before so we

375
00:14:29,970 --> 00:14:36,120
have $100 going to Bob but now there's a

376
00:14:33,180 --> 00:14:37,710
CSRF token field included which is it's

377
00:14:36,120 --> 00:14:39,720
basically the client echoing back the

378
00:14:37,710 --> 00:14:43,530
same token that it was given at the

379
00:14:39,720 --> 00:14:44,670
beginning now the server checks that and

380
00:14:43,530 --> 00:14:47,820
says is that the same as the one I gave

381
00:14:44,670 --> 00:14:50,340
you before if it is then it's gonna say

382
00:14:47,820 --> 00:14:52,220
this is a valid request and send back a

383
00:14:50,340 --> 00:14:58,230
page saying the transfer was successful

384
00:14:52,220 --> 00:14:59,550
right so so far so good right ok so now

385
00:14:58,230 --> 00:15:02,640
how does this protect us against an

386
00:14:59,550 --> 00:15:05,850
attacker you can imagine so this is the

387
00:15:02,640 --> 00:15:09,050
same situation as before we we user logs

388
00:15:05,850 --> 00:15:12,270
in with a username Alice and a password

389
00:15:09,050 --> 00:15:14,430
it's valid we get back the same

390
00:15:12,270 --> 00:15:15,800
pages before and now some time later

391
00:15:14,430 --> 00:15:19,400
they happen to visit an attacker site

392
00:15:15,800 --> 00:15:23,730
the attacker sends back some HTML and

393
00:15:19,400 --> 00:15:26,160
when that page loads that that attacker

394
00:15:23,730 --> 00:15:27,240
page sends a request to the server and

395
00:15:26,160 --> 00:15:30,060
this request is coming from this

396
00:15:27,240 --> 00:15:32,970
attacker attacker controlled this and so

397
00:15:30,060 --> 00:15:36,810
the question is what does the attacker

398
00:15:32,970 --> 00:15:38,820
put in here for the CSRF token field it

399
00:15:36,810 --> 00:15:42,750
should be the ABC that it was sent from

400
00:15:38,820 --> 00:15:44,160
before but because this form submission

401
00:15:42,750 --> 00:15:47,120
that's happening here this post request

402
00:15:44,160 --> 00:15:50,160
is coming from the attackers JavaScript

403
00:15:47,120 --> 00:15:55,020
the attacker actually has no way to read

404
00:15:50,160 --> 00:15:56,760
this input out of the victim com page in

405
00:15:55,020 --> 00:15:58,620
order to do that it would need to be

406
00:15:56,760 --> 00:16:00,420
able to reach into the Dom of victim com

407
00:15:58,620 --> 00:16:03,840
which is a violation of the same origin

408
00:16:00,420 --> 00:16:05,400
policy okay so basically this server

409
00:16:03,840 --> 00:16:08,610
here the victim com server when it looks

410
00:16:05,400 --> 00:16:10,020
at this request if it sees that the CSRF

411
00:16:08,610 --> 00:16:11,610
token is the same as before it knows

412
00:16:10,020 --> 00:16:13,590
that this request must have come from

413
00:16:11,610 --> 00:16:15,120
from the HTML and the JavaScript that

414
00:16:13,590 --> 00:16:16,680
it's sent down in the original page and

415
00:16:15,120 --> 00:16:19,290
not from some other website that the

416
00:16:16,680 --> 00:16:20,760
user happens to be on right so even

417
00:16:19,290 --> 00:16:22,740
though the cookie is here is valid right

418
00:16:20,760 --> 00:16:24,150
so the this attacker happened to send

419
00:16:22,740 --> 00:16:26,100
this request right and the browser

420
00:16:24,150 --> 00:16:27,120
attached the cookie so if the server

421
00:16:26,100 --> 00:16:28,380
would just to look at the cookie you

422
00:16:27,120 --> 00:16:29,610
would think that this is actually the

423
00:16:28,380 --> 00:16:32,070
user because they are they are logged in

424
00:16:29,610 --> 00:16:39,140
here but the CSRF token is wrong and so

425
00:16:32,070 --> 00:16:39,140
it's gonna reject the request right yeah

426
00:16:51,620 --> 00:16:57,570
so that's right so if if the server sees

427
00:16:55,530 --> 00:16:59,520
the CSRF token coming coming back from

428
00:16:57,570 --> 00:17:00,960
the client and it has ever given that

429
00:16:59,520 --> 00:17:02,640
token out to the user before it we need

430
00:17:00,960 --> 00:17:04,530
to like remember that and treat it as a

431
00:17:02,640 --> 00:17:06,390
valid like I could open up 10 tabs on a

432
00:17:04,530 --> 00:17:08,070
site so it's not enough for the server

433
00:17:06,390 --> 00:17:09,480
to remember the last token it sent out

434
00:17:08,070 --> 00:17:11,610
it has like remember all of them right

435
00:17:09,480 --> 00:17:13,830
and so typically what we actually do is

436
00:17:11,610 --> 00:17:15,510
we we don't want to we don't want to

437
00:17:13,830 --> 00:17:16,890
just generate a random value so if I go

438
00:17:15,510 --> 00:17:18,510
back to that slide where we were showing

439
00:17:16,890 --> 00:17:19,800
the code here this is not a very good

440
00:17:18,510 --> 00:17:21,240
approach because it means that the

441
00:17:19,800 --> 00:17:23,760
server has to basically remember every

442
00:17:21,240 --> 00:17:24,930
single CSRF token that it's ever sent to

443
00:17:23,760 --> 00:17:25,620
the user for some reasonable amount of

444
00:17:24,930 --> 00:17:27,360
time

445
00:17:25,620 --> 00:17:29,600
and better ways you can just say look

446
00:17:27,360 --> 00:17:31,740
whatever session idea I gave the user I

447
00:17:29,600 --> 00:17:34,080
already set that in a cookie the user

448
00:17:31,740 --> 00:17:36,780
has that in their browser right and so

449
00:17:34,080 --> 00:17:39,330
when they send it back to me if I just

450
00:17:36,780 --> 00:17:41,250
can compute what the token should be

451
00:17:39,330 --> 00:17:43,080
based off of that and I combined it with

452
00:17:41,250 --> 00:17:44,700
a secret that only the server knows and

453
00:17:43,080 --> 00:17:46,350
use this H Mac function which is you can

454
00:17:44,700 --> 00:17:50,309
think like a hash it's basically hashing

455
00:17:46,350 --> 00:17:53,250
the session ID with some secret that the

456
00:17:50,309 --> 00:17:54,809
server has and what's great about this

457
00:17:53,250 --> 00:17:56,970
is all the server has to remember is

458
00:17:54,809 --> 00:17:58,710
that this one secret and the client is

459
00:17:56,970 --> 00:18:03,000
going to provide them a session ID in

460
00:17:58,710 --> 00:18:04,740
the request as well as a token and as

461
00:18:03,000 --> 00:18:06,330
long as the server runs the same

462
00:18:04,740 --> 00:18:07,920
function when it's verifying the token

463
00:18:06,330 --> 00:18:09,780
as it did when it's sent down the token

464
00:18:07,920 --> 00:18:10,890
which is this function here then it

465
00:18:09,780 --> 00:18:12,510
should check out it should be it should

466
00:18:10,890 --> 00:18:14,160
be exactly the same and so the server

467
00:18:12,510 --> 00:18:15,059
can actually be completely stateless it

468
00:18:14,160 --> 00:18:16,590
doesn't need to remember any of these

469
00:18:15,059 --> 00:18:29,580
tokens and it can still verify that

470
00:18:16,590 --> 00:18:31,500
they're correct yeah that's okay yeah so

471
00:18:29,580 --> 00:18:33,750
so it's true it's not completely random

472
00:18:31,500 --> 00:18:35,940
from from page to page it's gonna be the

473
00:18:33,750 --> 00:18:37,200
users gonna be getting the same CSRF

474
00:18:35,940 --> 00:18:39,960
token as long as they have this session

475
00:18:37,200 --> 00:18:42,690
ID it's okay though because we're

476
00:18:39,960 --> 00:18:44,130
assuming here that the user is not going

477
00:18:42,690 --> 00:18:45,480
to share this with anybody and the

478
00:18:44,130 --> 00:18:49,670
attacker can't guess it and that's all

479
00:18:45,480 --> 00:18:49,670
we care about yeah

480
00:19:01,820 --> 00:19:06,960
it's it's it's similar you you know it

481
00:19:04,980 --> 00:19:09,030
is a very similar concept the difference

482
00:19:06,960 --> 00:19:10,890
is just where we're using it so the

483
00:19:09,030 --> 00:19:14,429
nonce field that you're talking about is

484
00:19:10,890 --> 00:19:16,380
from CSP and that's where the the server

485
00:19:14,429 --> 00:19:18,480
was telling the browser in a header

486
00:19:16,380 --> 00:19:20,280
don't run any scripts unless they

487
00:19:18,480 --> 00:19:22,679
contain this nan says an attribute and

488
00:19:20,280 --> 00:19:25,080
here it's actually the server that's

489
00:19:22,679 --> 00:19:27,360
saying the server is basically saying I

490
00:19:25,080 --> 00:19:28,980
won't accept any form submissions unless

491
00:19:27,360 --> 00:19:31,140
they include this value that I

492
00:19:28,980 --> 00:19:36,419
previously told to the client yeah but

493
00:19:31,140 --> 00:19:37,740
it it's very similar concepts yeah cool

494
00:19:36,419 --> 00:19:39,179
are there any questions about this this

495
00:19:37,740 --> 00:19:41,400
is important to understand the github

496
00:19:39,179 --> 00:19:45,260
attack which is really cool so yeah ask

497
00:19:41,400 --> 00:19:50,090
questions if you if you missed anything

498
00:19:45,260 --> 00:19:50,090
so the reason why I've questioned yeah

499
00:19:53,900 --> 00:19:59,790
that's correct yeah so if the same site

500
00:19:58,110 --> 00:20:01,500
cookie header was sent then then this

501
00:19:59,790 --> 00:20:02,850
attacker requests right here that the

502
00:20:01,500 --> 00:20:04,890
attacker sent wouldn't even include the

503
00:20:02,850 --> 00:20:07,230
cookies and so this wouldn't do anything

504
00:20:04,890 --> 00:20:09,150
yeah so you could use both together if

505
00:20:07,230 --> 00:20:10,290
you're like one one actually one use

506
00:20:09,150 --> 00:20:11,429
case for still using this as if you're

507
00:20:10,290 --> 00:20:12,990
if you have users that are on really old

508
00:20:11,429 --> 00:20:14,130
browsers like maybe you're building an

509
00:20:12,990 --> 00:20:17,280
enterprise app or something like that

510
00:20:14,130 --> 00:20:18,750
and you care about this the other place

511
00:20:17,280 --> 00:20:20,669
where you might see this is if you're

512
00:20:18,750 --> 00:20:25,799
using a web framework like Ruby on Rails

513
00:20:20,669 --> 00:20:27,809
or I guess I don't think Express builds

514
00:20:25,799 --> 00:20:29,730
it in but it's a it's a popular package

515
00:20:27,809 --> 00:20:31,140
that people include because like I said

516
00:20:29,730 --> 00:20:32,760
until recently there was no way to

517
00:20:31,140 --> 00:20:34,410
protect against this so literally every

518
00:20:32,760 --> 00:20:36,299
site out there on the internet had to

519
00:20:34,410 --> 00:20:38,160
implement this this protection at their

520
00:20:36,299 --> 00:20:40,169
in their own app code basically although

521
00:20:38,160 --> 00:20:42,690
the framework might give you some

522
00:20:40,169 --> 00:20:45,090
affordances for you to make it easier

523
00:20:42,690 --> 00:20:47,190
but um yeah the browser didn't help you

524
00:20:45,090 --> 00:20:48,750
at all here so if you're looking at code

525
00:20:47,190 --> 00:20:50,220
like at a company or at an internship or

526
00:20:48,750 --> 00:20:52,410
when you get a job after after college

527
00:20:50,220 --> 00:20:53,790
you very well might see CSRF token still

528
00:20:52,410 --> 00:20:57,020
because it's just probably in a lot of

529
00:20:53,790 --> 00:20:57,020
code bases still yeah

530
00:21:01,519 --> 00:21:04,499
so CEO surf tokens are perfectly

531
00:21:04,110 --> 00:21:06,809
effective

532
00:21:04,499 --> 00:21:08,249
yeah they completely like this basically

533
00:21:06,809 --> 00:21:10,710
as long as you're choosing this token

534
00:21:08,249 --> 00:21:12,269
from a big enough range and you're

535
00:21:10,710 --> 00:21:13,440
choosing it completely randomly then

536
00:21:12,269 --> 00:21:16,080
it's impossible for the attacker to

537
00:21:13,440 --> 00:21:19,350
guess it right they can't like send like

538
00:21:16,080 --> 00:21:20,700
a you know 20 billion requests with all

539
00:21:19,350 --> 00:21:22,740
possible tokens it's not it's not

540
00:21:20,700 --> 00:21:24,899
feasible so this is a very very

541
00:21:22,740 --> 00:21:27,299
effective defense same-side cookies are

542
00:21:24,899 --> 00:21:29,789
just introduced as as a way of saying

543
00:21:27,299 --> 00:21:31,110
wait a minute why do we have to have all

544
00:21:29,789 --> 00:21:33,230
this logic for the server to generate

545
00:21:31,110 --> 00:21:35,100
this this nonce and then check it and

546
00:21:33,230 --> 00:21:36,360
everybody's doing it separately and own

547
00:21:35,100 --> 00:21:37,740
if you forget to do it on one endpoint

548
00:21:36,360 --> 00:21:40,470
then your app whole app is vulnerable

549
00:21:37,740 --> 00:21:41,909
why don't we just say add one attribute

550
00:21:40,470 --> 00:21:44,159
to the cookie when we set it and just

551
00:21:41,909 --> 00:21:45,980
say same site and we're done you know

552
00:21:44,159 --> 00:22:03,360
like it's just a much simpler solution

553
00:21:45,980 --> 00:22:06,240
much less error-prone yeah I don't think

554
00:22:03,360 --> 00:22:07,919
that the attacker can control the refer

555
00:22:06,240 --> 00:22:09,360
header to that degree but they can they

556
00:22:07,919 --> 00:22:11,639
can omit it they can cause it to be

557
00:22:09,360 --> 00:22:13,019
omitted and then the server would have

558
00:22:11,639 --> 00:22:15,029
to decide what to do

559
00:22:13,019 --> 00:22:17,220
is it omitted for malicious reasons or

560
00:22:15,029 --> 00:22:18,509
did it did it get omitted for it because

561
00:22:17,220 --> 00:22:21,149
the browser is trying to be more private

562
00:22:18,509 --> 00:22:25,309
like it's unclear what the server should

563
00:22:21,149 --> 00:22:28,309
do does that answer your question

564
00:22:25,309 --> 00:22:28,309
cool

565
00:22:29,179 --> 00:22:33,379
cool okay so so now we understand CEO

566
00:22:31,969 --> 00:22:36,499
surf tokens great so let's talk about

567
00:22:33,379 --> 00:22:39,219
the attack so I think I think we have

568
00:22:36,499 --> 00:22:42,320
everything we need for now to explain it

569
00:22:39,219 --> 00:22:44,119
okay so so this is the prompt that a

570
00:22:42,320 --> 00:22:45,769
user sees when they're being asked if

571
00:22:44,119 --> 00:22:47,539
they would like to give an app

572
00:22:45,769 --> 00:22:50,179
permission to access their github

573
00:22:47,539 --> 00:22:51,229
account and if they decide they want to

574
00:22:50,179 --> 00:22:54,229
give the permission then they can click

575
00:22:51,229 --> 00:22:56,989
this authorize button here and for this

576
00:22:54,229 --> 00:22:58,489
demo he only chose to get like a very

577
00:22:56,989 --> 00:22:59,869
minimal set of permissions but this

578
00:22:58,489 --> 00:23:04,210
could have contained like a lot more

579
00:22:59,869 --> 00:23:06,589
prompts potentially for more more access

580
00:23:04,210 --> 00:23:08,299
okay so what is the flow like when

581
00:23:06,589 --> 00:23:10,759
you're actually authorizing an

582
00:23:08,299 --> 00:23:12,379
application so say that some third-party

583
00:23:10,759 --> 00:23:13,940
app once access to your github account

584
00:23:12,379 --> 00:23:16,070
for some legitimate purpose the way it

585
00:23:13,940 --> 00:23:18,830
works is it's gonna redirect you to this

586
00:23:16,070 --> 00:23:21,619
URL here github.com slash login / o auth

587
00:23:18,830 --> 00:23:22,969
slash authorize and it's going to

588
00:23:21,619 --> 00:23:25,639
include some information in the query

589
00:23:22,969 --> 00:23:27,139
string saying what app is owned by that

590
00:23:25,639 --> 00:23:28,700
developer so you're gonna get a prompt

591
00:23:27,139 --> 00:23:31,729
for that app saying this app once here

592
00:23:28,700 --> 00:23:33,019
once access to your account and so

593
00:23:31,729 --> 00:23:34,549
you've when you when you go there you're

594
00:23:33,019 --> 00:23:36,399
gonna get this authorization page that's

595
00:23:34,549 --> 00:23:39,859
the page we saw before it's this page

596
00:23:36,399 --> 00:23:41,599
okay so if the user chooses to grant

597
00:23:39,859 --> 00:23:43,450
access to the app and they click the big

598
00:23:41,599 --> 00:23:45,739
green button authorize on the page and

599
00:23:43,450 --> 00:23:48,019
then the user gets redirected back to

600
00:23:45,739 --> 00:23:49,639
the third party application and github

601
00:23:48,019 --> 00:23:50,330
when it does that redirect back it

602
00:23:49,639 --> 00:23:52,039
includes

603
00:23:50,330 --> 00:23:55,070
a query something in the query string

604
00:23:52,039 --> 00:23:57,919
which is basically a github token that

605
00:23:55,070 --> 00:23:59,839
the application can use to then access

606
00:23:57,919 --> 00:24:02,690
your data by sending requests to github

607
00:23:59,839 --> 00:24:03,739
like out-of-band right so this token is

608
00:24:02,690 --> 00:24:05,629
basically like the password to your

609
00:24:03,739 --> 00:24:11,749
account effectively for for this app

610
00:24:05,629 --> 00:24:14,179
right okay so that's the flow so how is

611
00:24:11,749 --> 00:24:15,799
the authorize button implemented so it

612
00:24:14,179 --> 00:24:17,570
turns out that you just did it as a form

613
00:24:15,799 --> 00:24:19,969
so the entire button is just an HTML

614
00:24:17,570 --> 00:24:23,559
form with one button in it when you

615
00:24:19,969 --> 00:24:23,559
click the button you submit the form and

616
00:24:23,710 --> 00:24:27,499
that form also happens to contain a

617
00:24:25,969 --> 00:24:30,739
hidden form field with a CSRF token

618
00:24:27,499 --> 00:24:32,239
inside of it okay so this is again this

619
00:24:30,739 --> 00:24:34,969
ensures that a random attacker can't

620
00:24:32,239 --> 00:24:36,200
just effectively click the button for

621
00:24:34,969 --> 00:24:39,339
you click the authorize button for you

622
00:24:36,200 --> 00:24:41,479
by by sending a post request to this URL

623
00:24:39,339 --> 00:24:42,740
so when their server receives these

624
00:24:41,479 --> 00:24:44,990
posts it's going to Val

625
00:24:42,740 --> 00:24:46,130
that the CSRF token is correct and then

626
00:24:44,990 --> 00:24:47,840
if it is it's going to assume that the

627
00:24:46,130 --> 00:24:49,010
user must have clicked this button by

628
00:24:47,840 --> 00:24:50,480
visiting the page directly and this

629
00:24:49,010 --> 00:24:53,059
request could not have come from some

630
00:24:50,480 --> 00:24:56,809
attacker site that's what the CSRF token

631
00:24:53,059 --> 00:24:59,390
gives us one interesting detail is the

632
00:24:56,809 --> 00:25:03,800
form actually submits to the exact same

633
00:24:59,390 --> 00:25:04,429
URL that the page is loaded from does

634
00:25:03,800 --> 00:25:07,520
that make sense

635
00:25:04,429 --> 00:25:09,230
so you the apt redirected the user to

636
00:25:07,520 --> 00:25:11,179
this URL and that loaded this sort of

637
00:25:09,230 --> 00:25:12,860
form with the big green button on it and

638
00:25:11,179 --> 00:25:14,929
then when you click the big green button

639
00:25:12,860 --> 00:25:17,600
that also sends a request to the same

640
00:25:14,929 --> 00:25:19,910
URL the only difference is that the

641
00:25:17,600 --> 00:25:23,300
first request was a get request and the

642
00:25:19,910 --> 00:25:25,429
form submission is a post request so the

643
00:25:23,300 --> 00:25:27,260
server can look at the HTTP method and

644
00:25:25,429 --> 00:25:30,679
then just do different things depending

645
00:25:27,260 --> 00:25:33,140
on what the method is that's an

646
00:25:30,679 --> 00:25:37,400
interesting detail to keep in mind okay

647
00:25:33,140 --> 00:25:38,690
so this is the full flow so we go to an

648
00:25:37,400 --> 00:25:40,700
app example outcome that we want to

649
00:25:38,690 --> 00:25:42,410
authenticate with or login with login to

650
00:25:40,700 --> 00:25:45,460
get hit with and it's gonna set us back

651
00:25:42,410 --> 00:25:50,620
a page with a login with github button

652
00:25:45,460 --> 00:25:53,690
and say the user clicks the button the

653
00:25:50,620 --> 00:25:56,179
button goes to this URL here login

654
00:25:53,690 --> 00:25:58,910
ooofff authorize and that request goes

655
00:25:56,179 --> 00:25:59,990
to github there might also be like I

656
00:25:58,910 --> 00:26:01,790
said some query parameters here that

657
00:25:59,990 --> 00:26:03,620
specify exactly what app we are trying

658
00:26:01,790 --> 00:26:05,600
to give access to our account but I just

659
00:26:03,620 --> 00:26:06,950
I didn't room in the slides and you'll

660
00:26:05,600 --> 00:26:09,290
notice here the cookies attached right

661
00:26:06,950 --> 00:26:12,380
because this is a get request the

662
00:26:09,290 --> 00:26:14,320
browser navigated there so of course the

663
00:26:12,380 --> 00:26:16,760
cookies are gonna get attached right

664
00:26:14,320 --> 00:26:18,559
okay so we're logged in to github so get

665
00:26:16,760 --> 00:26:18,920
hub is now gonna be like ah okay hi for

666
00:26:18,559 --> 00:26:20,600
us

667
00:26:18,920 --> 00:26:21,950
would you like to authorize this app so

668
00:26:20,600 --> 00:26:27,050
it sends back that page and that page

669
00:26:21,950 --> 00:26:29,530
includes the CSRF token so say the user

670
00:26:27,050 --> 00:26:31,760
clicks authorize now we're gonna post

671
00:26:29,530 --> 00:26:33,920
the form is going to get submitted via a

672
00:26:31,760 --> 00:26:36,190
post request to that same URL cookies

673
00:26:33,920 --> 00:26:39,350
attached CSRF token is attached right

674
00:26:36,190 --> 00:26:42,170
and so the server github can check is a

675
00:26:39,350 --> 00:26:44,630
token valid look it is okay great so we

676
00:26:42,170 --> 00:26:46,130
will send back a successful response to

677
00:26:44,630 --> 00:26:48,530
the user and we'll redirect them with

678
00:26:46,130 --> 00:26:49,970
this 302 which is a HTTP redirect will

679
00:26:48,530 --> 00:26:52,400
redirect them back to example.com the

680
00:26:49,970 --> 00:26:54,169
app and will include a github token XYZ

681
00:26:52,400 --> 00:26:56,660
that the app can use to access this

682
00:26:54,169 --> 00:26:58,850
users account now and so then the user

683
00:26:56,660 --> 00:27:01,580
their browser gets redirected to the to

684
00:26:58,850 --> 00:27:03,740
the to the same page but now with this

685
00:27:01,580 --> 00:27:04,790
little parameter attached and that's the

686
00:27:03,740 --> 00:27:06,110
whole flow so that's how you log into

687
00:27:04,790 --> 00:27:07,370
github this is actually how you log into

688
00:27:06,110 --> 00:27:08,750
most apps like if you ever see login

689
00:27:07,370 --> 00:27:10,700
with Twitter login with it's something

690
00:27:08,750 --> 00:27:13,130
like this basically right this is the

691
00:27:10,700 --> 00:27:14,570
effective idea so the this this token is

692
00:27:13,130 --> 00:27:20,180
sort of the key to your account that the

693
00:27:14,570 --> 00:27:21,440
app can use okay so this seems fine

694
00:27:20,180 --> 00:27:23,600
right like where's the problem where's

695
00:27:21,440 --> 00:27:24,950
the bug seems like there's no problems

696
00:27:23,600 --> 00:27:29,570
here as long as we're actually checking

697
00:27:24,950 --> 00:27:31,310
the token okay so let's see what

698
00:27:29,570 --> 00:27:33,080
actually what they did so so this attack

699
00:27:31,310 --> 00:27:36,260
this some security researcher was able

700
00:27:33,080 --> 00:27:40,100
to get a copy of the github source code

701
00:27:36,260 --> 00:27:41,810
by doing an enterprise trial so he like

702
00:27:40,100 --> 00:27:43,820
pretended he was a company downloaded

703
00:27:41,810 --> 00:27:45,770
their source code and then it's very

704
00:27:43,820 --> 00:27:47,780
it's sort of obfuscated but found he

705
00:27:45,770 --> 00:27:49,640
found some code online which I office

706
00:27:47,780 --> 00:27:50,720
gated it to quite a degree so he's able

707
00:27:49,640 --> 00:27:53,000
to serve just like a look at the Ruby

708
00:27:50,720 --> 00:27:55,790
code that they wrote and he found this

709
00:27:53,000 --> 00:27:56,680
section in there and so this is the

710
00:27:55,790 --> 00:27:59,000
section that implements that

711
00:27:56,680 --> 00:28:01,730
authorization flow so let's see what

712
00:27:59,000 --> 00:28:04,850
it's doing so it says we have this URL

713
00:28:01,730 --> 00:28:07,370
here login ooofff authorize and any time

714
00:28:04,850 --> 00:28:09,830
a request comes in to that URL and it's

715
00:28:07,370 --> 00:28:12,830
a get or it's a post then we want it to

716
00:28:09,830 --> 00:28:15,980
go to this controller and you can think

717
00:28:12,830 --> 00:28:17,570
of controller is similar to handlers in

718
00:28:15,980 --> 00:28:20,920
Express so it's just the function that's

719
00:28:17,570 --> 00:28:23,360
gonna run to handle this request and so

720
00:28:20,920 --> 00:28:24,670
and so all gets and all posts to that

721
00:28:23,360 --> 00:28:27,260
URL are going to get handled by this

722
00:28:24,670 --> 00:28:29,930
function here and so this particular

723
00:28:27,260 --> 00:28:31,940
function happen to have an if-else check

724
00:28:29,930 --> 00:28:33,710
where we checked if the request is a get

725
00:28:31,940 --> 00:28:35,390
request then we're gonna serve them back

726
00:28:33,710 --> 00:28:37,550
to HTML with the big green button on it

727
00:28:35,390 --> 00:28:41,150
and if it's a post request then we're

728
00:28:37,550 --> 00:28:42,470
gonna check the CSRF token and if it's

729
00:28:41,150 --> 00:28:45,730
all valid then we're gonna grant the

730
00:28:42,470 --> 00:28:47,990
permission to use to use the application

731
00:28:45,730 --> 00:28:49,250
again so far so good I don't see any

732
00:28:47,990 --> 00:28:52,030
problems with this does anyone see any

733
00:28:49,250 --> 00:28:54,560
problems with this and problems right

734
00:28:52,030 --> 00:28:57,410
yeah I don't I don't think any of this

735
00:28:54,560 --> 00:28:59,780
is is bad so far okay one more thing I

736
00:28:57,410 --> 00:29:01,960
need to talk about and then you'll

737
00:28:59,780 --> 00:29:04,100
you'll see what the problem is so

738
00:29:01,960 --> 00:29:07,520
there's this thing called an HTTP header

739
00:29:04,100 --> 00:29:10,760
quest so a head request is basically

740
00:29:07,520 --> 00:29:12,200
like a get request the semantics are

741
00:29:10,760 --> 00:29:13,760
if you send ahead request to the server

742
00:29:12,200 --> 00:29:15,410
the server is supposed to treat it like

743
00:29:13,760 --> 00:29:17,120
a get request it's supposed to go and

744
00:29:15,410 --> 00:29:19,340
get whatever resource you asked to get

745
00:29:17,120 --> 00:29:21,260
and then before it sends back the

746
00:29:19,340 --> 00:29:24,440
response to you it just omits the body

747
00:29:21,260 --> 00:29:25,760
it sends all the headers and it just

748
00:29:24,440 --> 00:29:28,840
doesn't send you the actual page that

749
00:29:25,760 --> 00:29:31,370
you asked for so why is this useful

750
00:29:28,840 --> 00:29:34,100
you'll typically see head requests he

751
00:29:31,370 --> 00:29:35,480
used if like your browser before it

752
00:29:34,100 --> 00:29:36,980
downloads a file maybe it wants to see

753
00:29:35,480 --> 00:29:38,299
is this a huge file what's the size of

754
00:29:36,980 --> 00:29:40,280
this file so it could send a head

755
00:29:38,299 --> 00:29:42,980
request and then it'll get back at the

756
00:29:40,280 --> 00:29:44,780
headers and not the file and to look at

757
00:29:42,980 --> 00:29:46,880
the content length header and be like oh

758
00:29:44,780 --> 00:29:48,890
this is a gigabyte file ok but maybe

759
00:29:46,880 --> 00:29:50,330
that changes my strategy for how I'm

760
00:29:48,890 --> 00:29:52,130
gonna download this or something right

761
00:29:50,330 --> 00:29:54,290
so that's a common thing but it is

762
00:29:52,130 --> 00:29:57,350
relatively niche and relatively obscure

763
00:29:54,290 --> 00:29:59,570
most people aren't using head requests

764
00:29:57,350 --> 00:30:01,760
on a regular basis and so because of

765
00:29:59,570 --> 00:30:03,350
that Ruby on Rails which is the

766
00:30:01,760 --> 00:30:05,540
framework that github used

767
00:30:03,350 --> 00:30:06,919
it knows that most people aren't going

768
00:30:05,540 --> 00:30:08,540
to bother to implement a head request

769
00:30:06,919 --> 00:30:09,740
and so it's like well we can just do

770
00:30:08,540 --> 00:30:11,630
that for you basically we know what to

771
00:30:09,740 --> 00:30:12,890
do when there's a head request we

772
00:30:11,630 --> 00:30:14,840
basically just want to run the code that

773
00:30:12,890 --> 00:30:18,559
we were gonna do for get requests and

774
00:30:14,840 --> 00:30:20,900
then when that code is ready to send

775
00:30:18,559 --> 00:30:21,950
back the response we'll just tweak the

776
00:30:20,900 --> 00:30:23,540
response we'll just get rid of the body

777
00:30:21,950 --> 00:30:25,460
for them and send back just the headers

778
00:30:23,540 --> 00:30:28,520
right and so the framework is basically

779
00:30:25,460 --> 00:30:30,380
like we can help you out that it's so

780
00:30:28,520 --> 00:30:31,970
similar to get so why don't why not just

781
00:30:30,380 --> 00:30:33,200
handle it for the developer right most

782
00:30:31,970 --> 00:30:42,980
developers would forget to do head

783
00:30:33,200 --> 00:30:44,660
otherwise right mmm yeah that's great

784
00:30:42,980 --> 00:30:46,640
yeah yeah exactly so the reason why we

785
00:30:44,660 --> 00:30:48,230
can do this for head is because a get

786
00:30:46,640 --> 00:30:49,790
request isn't supposed to change

787
00:30:48,230 --> 00:30:51,919
anything it's not gonna make any it's

788
00:30:49,790 --> 00:30:52,910
not gonna be um I'm modifying the

789
00:30:51,919 --> 00:30:55,760
database it's not going to be

790
00:30:52,910 --> 00:30:57,140
destructive in any way you can repeat a

791
00:30:55,760 --> 00:30:59,059
get request as many times as you want

792
00:30:57,140 --> 00:31:00,500
and nothing is going to happen so so

793
00:30:59,059 --> 00:31:02,030
it's no big deal to send it to send a

794
00:31:00,500 --> 00:31:03,760
head request whereas yeah you could not

795
00:31:02,030 --> 00:31:10,120
do that with a poster with any other

796
00:31:03,760 --> 00:31:10,120
method cool any questions about head

797
00:31:10,570 --> 00:31:15,260
okay so that's how that's how that

798
00:31:12,380 --> 00:31:16,490
request works cool so so so Ruby on

799
00:31:15,260 --> 00:31:17,840
Rails like I mentioned it automatically

800
00:31:16,490 --> 00:31:19,850
is going to handle head requests for us

801
00:31:17,840 --> 00:31:21,620
so it does that by routing any head

802
00:31:19,850 --> 00:31:24,740
request that comes in to the same place

803
00:31:21,620 --> 00:31:26,660
as it was it would route get requests

804
00:31:24,740 --> 00:31:27,740
and an express actually does this too so

805
00:31:26,660 --> 00:31:30,140
it's not just the Ruby on Rails thing

806
00:31:27,740 --> 00:31:32,600
and so it's gonna run the same

807
00:31:30,140 --> 00:31:34,190
controller code that it would hand it

808
00:31:32,600 --> 00:31:36,770
would run forward get requests and then

809
00:31:34,190 --> 00:31:38,420
it's just gonna go ahead and delete the

810
00:31:36,770 --> 00:31:41,240
response body when it sends back the

811
00:31:38,420 --> 00:31:42,830
response and so this is a time-saving

812
00:31:41,240 --> 00:31:45,260
feature for developers it's usually the

813
00:31:42,830 --> 00:31:47,030
right behavior it's very handy that the

814
00:31:45,260 --> 00:31:48,290
framework does this for you there's one

815
00:31:47,030 --> 00:31:51,530
problem with it which is that it's a

816
00:31:48,290 --> 00:31:52,910
slightly leaky abstraction a leaky

817
00:31:51,530 --> 00:31:55,370
abstractions is just an abstraction that

818
00:31:52,910 --> 00:31:57,170
doesn't perfectly hide the complexity

819
00:31:55,370 --> 00:31:58,940
from the developer so most of the time

820
00:31:57,170 --> 00:32:01,250
the developer doesn't have to know this

821
00:31:58,940 --> 00:32:04,250
exists except for in this one case here

822
00:32:01,250 --> 00:32:06,580
where in the controller which is again

823
00:32:04,250 --> 00:32:09,410
the handler the function that's running

824
00:32:06,580 --> 00:32:11,600
the app in a check request dot gets

825
00:32:09,410 --> 00:32:13,310
question mark which is that's a ruby way

826
00:32:11,600 --> 00:32:14,630
of basically saying this is a boolean

827
00:32:13,310 --> 00:32:16,180
anything with a question mark on the end

828
00:32:14,630 --> 00:32:18,350
of it is boolean in Ruby it's like

829
00:32:16,180 --> 00:32:22,460
you're asking it sort of like is get

830
00:32:18,350 --> 00:32:26,480
basically um anyway so so that actually

831
00:32:22,460 --> 00:32:28,960
returns false for head requests this is

832
00:32:26,480 --> 00:32:31,640
kind of unexpected because the developer

833
00:32:28,960 --> 00:32:33,290
said that they wanted this controller to

834
00:32:31,640 --> 00:32:36,140
only run for get requests and post

835
00:32:33,290 --> 00:32:38,510
requests and so they may have made an

836
00:32:36,140 --> 00:32:40,820
assumption that I'm only going to ever

837
00:32:38,510 --> 00:32:41,990
get a get request for a post request and

838
00:32:40,820 --> 00:32:43,940
so if they have an if statement in their

839
00:32:41,990 --> 00:32:47,600
code like like this code happened to and

840
00:32:43,940 --> 00:32:48,680
it's checking this then their in this

841
00:32:47,600 --> 00:32:50,090
case there's going to be a third value

842
00:32:48,680 --> 00:32:51,980
there's going to be head requests coming

843
00:32:50,090 --> 00:32:53,810
through that same code path and so let's

844
00:32:51,980 --> 00:32:55,520
see what goes wrong when we do that so

845
00:32:53,810 --> 00:32:57,380
look at the code again again the

846
00:32:55,520 --> 00:32:59,090
developer said I only want get requests

847
00:32:57,380 --> 00:33:02,510
and post requests to go to this function

848
00:32:59,090 --> 00:33:03,980
and so they thought oh okay so this is

849
00:33:02,510 --> 00:33:07,370
gonna handle the gets and then the else

850
00:33:03,980 --> 00:33:09,200
is gonna handle the posts right but the

851
00:33:07,370 --> 00:33:14,950
head requests ended up in here as well

852
00:33:09,200 --> 00:33:14,950
right does every see that okay

853
00:33:19,420 --> 00:33:25,370
yes yeah so yeah this is this is only

854
00:33:23,690 --> 00:33:28,220
possible because they decided to sort of

855
00:33:25,370 --> 00:33:30,050
handle get and post in one controller

856
00:33:28,220 --> 00:33:31,130
function basically that's a really good

857
00:33:30,050 --> 00:33:32,330
point yeah this wouldn't happen

858
00:33:31,130 --> 00:33:34,310
otherwise

859
00:33:32,330 --> 00:33:35,360
so one important point is so you might

860
00:33:34,310 --> 00:33:36,350
think okay so what's the big deal so

861
00:33:35,360 --> 00:33:38,480
they're gonna somebody makes a head

862
00:33:36,350 --> 00:33:40,490
request to the server okay so we end up

863
00:33:38,480 --> 00:33:42,410
in this case there's still gonna be us

864
00:33:40,490 --> 00:33:44,540
they're still not gonna be a valid CSRF

865
00:33:42,410 --> 00:33:46,850
token right because remember the else

866
00:33:44,540 --> 00:33:48,350
case this is the the case where we're

867
00:33:46,850 --> 00:33:50,840
about to authorize an app so this is

868
00:33:48,350 --> 00:33:53,930
definitely gonna check that the CSRF

869
00:33:50,840 --> 00:33:55,580
token was included so an attacker still

870
00:33:53,930 --> 00:33:56,990
can't find out what the token is because

871
00:33:55,580 --> 00:33:58,370
it can't it can't violate the

872
00:33:56,990 --> 00:34:03,290
same-origin policy and go and read that

873
00:33:58,370 --> 00:34:04,490
input with the token in it right so so

874
00:34:03,290 --> 00:34:14,750
how does this actually turn into an

875
00:34:04,490 --> 00:34:17,120
attack so what happens is the CSRF token

876
00:34:14,750 --> 00:34:19,490
handling wasn't actually done directly

877
00:34:17,120 --> 00:34:21,410
in this else case a common thing that

878
00:34:19,490 --> 00:34:24,410
frameworks will do for you and in Ruby

879
00:34:21,410 --> 00:34:25,640
on Rails is is a prototypical example of

880
00:34:24,410 --> 00:34:27,050
this because it sort of tries to handle

881
00:34:25,640 --> 00:34:29,000
as much as possible for the developer

882
00:34:27,050 --> 00:34:31,490
what it does is it says okay we know

883
00:34:29,000 --> 00:34:33,770
that the user wants to validate CSRF

884
00:34:31,490 --> 00:34:36,020
tokens anytime there's a post request

885
00:34:33,770 --> 00:34:37,790
coming through so what it does is

886
00:34:36,020 --> 00:34:39,950
basically before any of this controller

887
00:34:37,790 --> 00:34:41,960
code even runs there's another function

888
00:34:39,950 --> 00:34:44,540
that runs in rails that says is this a

889
00:34:41,960 --> 00:34:47,560
post request if so check the CSRF token

890
00:34:44,540 --> 00:34:50,120
if it's invalid return an error page

891
00:34:47,560 --> 00:34:51,920
before this code would even run right

892
00:34:50,120 --> 00:34:54,860
and that's how you get CSRF token

893
00:34:51,920 --> 00:34:58,490
checking in rails and so the problem was

894
00:34:54,860 --> 00:34:59,630
when a head request comes in that's not

895
00:34:58,490 --> 00:35:02,990
going to trigger that CSRF token

896
00:34:59,630 --> 00:35:05,150
checking code right it's a head request

897
00:35:02,990 --> 00:35:06,740
not a post request so that's that that

898
00:35:05,150 --> 00:35:09,140
gets bypassed then we end up in the

899
00:35:06,740 --> 00:35:11,150
controller here and then head doesn't

900
00:35:09,140 --> 00:35:13,130
match this if case so it runs this code

901
00:35:11,150 --> 00:35:14,600
and then at this point we're not

902
00:35:13,130 --> 00:35:16,070
checking the CSRF token we've assumed

903
00:35:14,600 --> 00:35:17,720
that's already happened that rails took

904
00:35:16,070 --> 00:35:20,750
care of that for us and so literally you

905
00:35:17,720 --> 00:35:22,660
can omit the CSRF token and and Gabe's

906
00:35:20,750 --> 00:35:26,240
gonna say oh that looks legit to me and

907
00:35:22,660 --> 00:35:27,650
authorize the application so yeah I mean

908
00:35:26,240 --> 00:35:29,270
basically you just send a head request

909
00:35:27,650 --> 00:35:31,470
with to the app you want and then that

910
00:35:29,270 --> 00:35:33,690
user just automatically accepts that

911
00:35:31,470 --> 00:35:36,930
on their account one request very very

912
00:35:33,690 --> 00:35:38,430
very elegant yeah so let's see what that

913
00:35:36,930 --> 00:35:40,200
looks like in action so this is is now

914
00:35:38,430 --> 00:35:42,210
fixed this was two weeks ago yet have

915
00:35:40,200 --> 00:35:43,740
actually responded to the hacker one

916
00:35:42,210 --> 00:35:45,030
report remember hacker while I was what

917
00:35:43,740 --> 00:35:46,680
miles talked about last time that's

918
00:35:45,030 --> 00:35:48,270
where your poor bugs they responded in

919
00:35:46,680 --> 00:35:49,829
eight minutes and acknowledged it and

920
00:35:48,270 --> 00:35:51,089
they were like yep yep we confirmed it

921
00:35:49,829 --> 00:35:52,680
it was very easy for them to test it

922
00:35:51,089 --> 00:35:53,750
they just like sent ahead it goes oh

923
00:35:52,680 --> 00:35:56,160
crap

924
00:35:53,750 --> 00:35:58,109
and then they acknowledged it right away

925
00:35:56,160 --> 00:36:00,270
and then they had it fixed out in three

926
00:35:58,109 --> 00:36:01,890
hours like there's a very very severe

927
00:36:00,270 --> 00:36:03,420
issues so they were they were on it

928
00:36:01,890 --> 00:36:06,869
right away but props to them for being

929
00:36:03,420 --> 00:36:09,450
so fast yeah so this is fixed as of like

930
00:36:06,869 --> 00:36:10,920
two weeks ago but this is how how the

931
00:36:09,450 --> 00:36:13,410
attack would have worked so you visit

932
00:36:10,920 --> 00:36:14,520
the attacker server again remember this

933
00:36:13,410 --> 00:36:16,170
is really easy to do you just click a

934
00:36:14,520 --> 00:36:18,270
link right you end up on you end up on

935
00:36:16,170 --> 00:36:21,750
an attackers page you get back some HTML

936
00:36:18,270 --> 00:36:24,630
and that HTML causes a request to go to

937
00:36:21,750 --> 00:36:26,760
github it's a head request to authorize

938
00:36:24,630 --> 00:36:29,550
and then there's a app ID attached here

939
00:36:26,760 --> 00:36:32,160
to the to the URL and your cookies are

940
00:36:29,550 --> 00:36:34,020
sent and there's no CSRF token in sight

941
00:36:32,160 --> 00:36:35,480
and the server just doesn't doesn't

942
00:36:34,020 --> 00:36:38,730
bother checking it just sends you back

943
00:36:35,480 --> 00:36:40,200
your authorized and then of course

944
00:36:38,730 --> 00:36:41,460
that's going to redirect you to the oh I

945
00:36:40,200 --> 00:36:44,400
guess I messed this up this should say

946
00:36:41,460 --> 00:36:46,819
attacker comm so it redirects you to the

947
00:36:44,400 --> 00:36:48,680
attacker calm server with get up token

948
00:36:46,819 --> 00:36:59,579
just like that

949
00:36:48,680 --> 00:37:02,849
yeah pretty crazy interesting yeah I

950
00:36:59,579 --> 00:37:05,010
mean it should I I'm not too familiar

951
00:37:02,849 --> 00:37:06,480
with with the kinds of stuff that people

952
00:37:05,010 --> 00:37:07,740
are using like in production in the real

953
00:37:06,480 --> 00:37:09,119
world on their on their applications

954
00:37:07,740 --> 00:37:10,410
like there's all kinds of there's like

955
00:37:09,119 --> 00:37:12,480
hundreds or thousands of security

956
00:37:10,410 --> 00:37:14,250
vendors I'm sure some vendor claims that

957
00:37:12,480 --> 00:37:16,200
they can do this I don't know I'm how

958
00:37:14,250 --> 00:37:18,030
effective it is I would I would guess

959
00:37:16,200 --> 00:37:21,270
the hard part about that is like it

960
00:37:18,030 --> 00:37:22,230
would need to you'd only catch this if

961
00:37:21,270 --> 00:37:24,599
you were actually sending it with a

962
00:37:22,230 --> 00:37:27,180
valid cookie so that the the fuzzer

963
00:37:24,599 --> 00:37:28,470
would have to be smart enough to to to

964
00:37:27,180 --> 00:37:30,930
like figure out how to send like a

965
00:37:28,470 --> 00:37:36,589
mostly legit request if it could yeah we

966
00:37:30,930 --> 00:37:36,589
catch this yeah did you of course Mina

967
00:37:49,270 --> 00:37:55,850
so Express is very much modular so it

968
00:37:53,900 --> 00:37:58,490
doesn't actually do any CSRF checking

969
00:37:55,850 --> 00:38:00,500
out of the box but there's like a common

970
00:37:58,490 --> 00:38:01,940
set of like five or ten packages that

971
00:38:00,500 --> 00:38:03,500
everybody who's using Express pretty

972
00:38:01,940 --> 00:38:05,600
much also installs and one of them is

973
00:38:03,500 --> 00:38:09,650
called C surf which is I don't know some

974
00:38:05,600 --> 00:38:12,050
weird plan on CSRF and and so that that

975
00:38:09,650 --> 00:38:14,480
package would if you used it in this way

976
00:38:12,050 --> 00:38:16,250
it would you would configure it usually

977
00:38:14,480 --> 00:38:18,800
to only check against post requests so

978
00:38:16,250 --> 00:38:21,410
you'd have the same problem yeah if you

979
00:38:18,800 --> 00:38:26,900
were purely relying on like you know on

980
00:38:21,410 --> 00:38:28,070
that check on post requests now we'll

981
00:38:26,900 --> 00:38:29,660
get to it in a sec but there's other way

982
00:38:28,070 --> 00:38:31,280
there's actually other reasons why this

983
00:38:29,660 --> 00:38:32,780
would be less likely to happen in

984
00:38:31,280 --> 00:38:37,400
Express I'll mention I'll try to mention

985
00:38:32,780 --> 00:38:39,350
it at the end of the next slide so let's

986
00:38:37,400 --> 00:38:42,770
think about how github could have

987
00:38:39,350 --> 00:38:55,820
prevented this does anyone have some

988
00:38:42,770 --> 00:38:58,100
ideas yeah yeah that's a super easy way

989
00:38:55,820 --> 00:39:00,170
to do it yeah that's like a great way to

990
00:38:58,100 --> 00:39:01,730
code defensively basically don't assume

991
00:39:00,170 --> 00:39:03,260
that you know that though the two

992
00:39:01,730 --> 00:39:04,400
options are get and post just be like

993
00:39:03,260 --> 00:39:08,630
I'm paranoid I don't know what's gonna

994
00:39:04,400 --> 00:39:09,950
get called here at else else if requests

995
00:39:08,630 --> 00:39:12,050
post and then I would actually suggest

996
00:39:09,950 --> 00:39:12,980
also throwing in and else at the end

997
00:39:12,050 --> 00:39:14,570
just think I don't know if there's

998
00:39:12,980 --> 00:39:15,980
actually code after this this section

999
00:39:14,570 --> 00:39:17,680
here but you wouldn't want that you

1000
00:39:15,980 --> 00:39:19,970
wouldnt want to just skip both of these

1001
00:39:17,680 --> 00:39:22,640
cases and then just run like other code

1002
00:39:19,970 --> 00:39:24,680
afterwards in the in the head case

1003
00:39:22,640 --> 00:39:26,300
so I would actually say I would say do

1004
00:39:24,680 --> 00:39:28,370
this if it's a get do this if it's a

1005
00:39:26,300 --> 00:39:32,660
post throw an exception if it's anything

1006
00:39:28,370 --> 00:39:35,150
else this is this is a very sort of

1007
00:39:32,660 --> 00:39:36,560
common paradigm you'll see if you're

1008
00:39:35,150 --> 00:39:38,720
coding defensively you'll basically want

1009
00:39:36,560 --> 00:39:41,420
to say I expect this to be the case if

1010
00:39:38,720 --> 00:39:43,280
it is not and that would be really bad

1011
00:39:41,420 --> 00:39:45,740
for some reason like if the if this is

1012
00:39:43,280 --> 00:39:48,380
not the not what I assume to be the case

1013
00:39:45,740 --> 00:39:49,339
then you want to just sort of bail out

1014
00:39:48,380 --> 00:39:52,460
as soon as you can you want

1015
00:39:49,339 --> 00:39:54,559
just abort crash the process because the

1016
00:39:52,460 --> 00:39:56,269
nice thing is if you crash here sure

1017
00:39:54,559 --> 00:39:57,440
that means now that's you know some

1018
00:39:56,269 --> 00:39:58,819
attacker has now figured out if they

1019
00:39:57,440 --> 00:40:01,279
send ahead request to your server they

1020
00:39:58,819 --> 00:40:02,599
can cause it to crash right that's still

1021
00:40:01,279 --> 00:40:05,029
much better than the bug that could have

1022
00:40:02,599 --> 00:40:07,369
ended up with by not doing this and the

1023
00:40:05,029 --> 00:40:09,109
nice thing about crashes is typically in

1024
00:40:07,369 --> 00:40:10,670
production right you have like hundreds

1025
00:40:09,109 --> 00:40:12,650
or thousands of instances of your app

1026
00:40:10,670 --> 00:40:15,979
running and if an attacker can crash one

1027
00:40:12,650 --> 00:40:17,299
of them or many of them sure they affect

1028
00:40:15,979 --> 00:40:18,559
the availability of your site in some

1029
00:40:17,299 --> 00:40:19,940
way but you're going to get an email or

1030
00:40:18,559 --> 00:40:21,589
some kind of an alert right away saying

1031
00:40:19,940 --> 00:40:22,700
there was an exception in production and

1032
00:40:21,589 --> 00:40:24,619
you're gonna look at it and you're gonna

1033
00:40:22,700 --> 00:40:28,130
say this case was never supposed to run

1034
00:40:24,619 --> 00:40:29,660
ever and it just did ok one of our like

1035
00:40:28,130 --> 00:40:31,430
my assumptions were violated in a very

1036
00:40:29,660 --> 00:40:33,589
serious way and you'll immediately sort

1037
00:40:31,430 --> 00:40:34,849
of debug it and be like oh head requests

1038
00:40:33,589 --> 00:40:36,710
can come to this code and you

1039
00:40:34,849 --> 00:40:39,219
immediately then you know figure out the

1040
00:40:36,710 --> 00:40:41,599
problem and fix the root cause I'm so

1041
00:40:39,219 --> 00:40:51,170
asserting that your assumptions are true

1042
00:40:41,599 --> 00:40:58,729
is a really good idea like check to see

1043
00:40:51,170 --> 00:41:00,829
if it actually got validated yeah I

1044
00:40:58,729 --> 00:41:02,599
don't know if rails is gonna expose that

1045
00:41:00,829 --> 00:41:04,609
and enough detail to you because it is

1046
00:41:02,599 --> 00:41:06,759
being handled it like another level but

1047
00:41:04,609 --> 00:41:08,839
yeah if it did you could do that yeah

1048
00:41:06,759 --> 00:41:10,160
any other ideas there's other there's

1049
00:41:08,839 --> 00:41:11,479
many other ways we could have let me go

1050
00:41:10,160 --> 00:41:33,710
back to the code actually any other

1051
00:41:11,479 --> 00:41:35,269
ideas because it's such a sensitive

1052
00:41:33,710 --> 00:41:37,460
things like your entire github account

1053
00:41:35,269 --> 00:41:38,869
yeah there's something to that I mean

1054
00:41:37,460 --> 00:41:42,079
you're basically suggesting being

1055
00:41:38,869 --> 00:41:44,809
explicit and less magical and I'm a fan

1056
00:41:42,079 --> 00:41:45,799
of this as well in general I mean so

1057
00:41:44,809 --> 00:41:48,170
it's a trait it's always a trade-off

1058
00:41:45,799 --> 00:41:49,940
like if you if you require the user to

1059
00:41:48,170 --> 00:41:52,969
be explicit and they forget in one place

1060
00:41:49,940 --> 00:41:54,410
right or you you have a new developer on

1061
00:41:52,969 --> 00:41:56,420
your team who just joined and they don't

1062
00:41:54,410 --> 00:41:57,499
know like they're just learning rails

1063
00:41:56,420 --> 00:41:59,210
for the first time they've been coding

1064
00:41:57,499 --> 00:42:00,769
in something else they're gonna you know

1065
00:41:59,210 --> 00:42:02,990
you're more likely to make a mistake

1066
00:42:00,769 --> 00:42:05,060
maybe on the other hand

1067
00:42:02,990 --> 00:42:06,589
relying on magical behavior that you

1068
00:42:05,060 --> 00:42:08,599
don't fully understand can bite you as

1069
00:42:06,589 --> 00:42:22,790
this case has demonstrated so it's it's

1070
00:42:08,599 --> 00:42:24,800
a trade-off yeah mm-hmm yeah exactly

1071
00:42:22,790 --> 00:42:26,240
yeah so I wouldn't have tried to be so

1072
00:42:24,800 --> 00:42:27,619
clever and be like oh I'm gonna I mean

1073
00:42:26,240 --> 00:42:29,990
the nice thing about what you're

1074
00:42:27,619 --> 00:42:31,730
suggesting is what you're saying doesn't

1075
00:42:29,990 --> 00:42:33,109
even require them to require to use two

1076
00:42:31,730 --> 00:42:34,250
different URLs they could still do this

1077
00:42:33,109 --> 00:42:36,320
thing where they're they're using the

1078
00:42:34,250 --> 00:42:38,359
same URL for both but they they could

1079
00:42:36,320 --> 00:42:41,030
tell rails that they want a different

1080
00:42:38,359 --> 00:42:42,080
controller forget and then for post so

1081
00:42:41,030 --> 00:42:45,020
they have two different functions one

1082
00:42:42,080 --> 00:42:46,280
for get one for post and and that would

1083
00:42:45,020 --> 00:42:48,650
have that would have solved the problem

1084
00:42:46,280 --> 00:42:49,940
yeah so one of the nice things about

1085
00:42:48,650 --> 00:42:51,680
Express I'll mention it now since this

1086
00:42:49,940 --> 00:42:53,990
is actually totally relevant but with

1087
00:42:51,680 --> 00:42:57,890
express you usually say app get app top

1088
00:42:53,990 --> 00:42:59,780
post you register your method upfront

1089
00:42:57,890 --> 00:43:01,970
and you can only pick one you can't do

1090
00:42:59,780 --> 00:43:04,670
this like oh get and post and whatever

1091
00:43:01,970 --> 00:43:06,470
you can't mix the two um the exception

1092
00:43:04,670 --> 00:43:08,780
is there's this thing called app dot use

1093
00:43:06,470 --> 00:43:10,670
in Express and with that you're

1094
00:43:08,780 --> 00:43:12,589
basically saying I want all HTTP methods

1095
00:43:10,670 --> 00:43:15,500
to come to this function and get handled

1096
00:43:12,589 --> 00:43:17,060
by this function at which point you now

1097
00:43:15,500 --> 00:43:18,830
like all bets are off you have to

1098
00:43:17,060 --> 00:43:20,119
basically handle every method so an

1099
00:43:18,830 --> 00:43:23,570
express are either handle every method

1100
00:43:20,119 --> 00:43:24,740
or you handle one method and even though

1101
00:43:23,570 --> 00:43:28,810
it's so even though it is automatically

1102
00:43:24,740 --> 00:43:32,180
sending head requests to the get handler

1103
00:43:28,810 --> 00:43:33,410
there's nothing that can go wrong in

1104
00:43:32,180 --> 00:43:40,369
that case because there's no post code

1105
00:43:33,410 --> 00:43:41,450
in that same path that makes sense okay

1106
00:43:40,369 --> 00:43:45,170
keep going

1107
00:43:41,450 --> 00:43:46,760
oh did anybody have any other ideas for

1108
00:43:45,170 --> 00:43:52,580
how I could have prevented it before you

1109
00:43:46,760 --> 00:43:53,570
move on okay so yeah we talked about

1110
00:43:52,580 --> 00:43:55,010
most of these oh yeah and then obviously

1111
00:43:53,570 --> 00:43:56,150
the most obvious one of all that no one

1112
00:43:55,010 --> 00:43:58,640
said is we could just have used the same

1113
00:43:56,150 --> 00:43:59,960
side cookies instead of CSRF tokens and

1114
00:43:58,640 --> 00:44:03,500
then we wouldn't have had to deal with

1115
00:43:59,960 --> 00:44:05,030
any of this complexity but yeah so using

1116
00:44:03,500 --> 00:44:07,250
a separate controller would have worked

1117
00:44:05,030 --> 00:44:08,750
using separate URLs for the

1118
00:44:07,250 --> 00:44:10,820
authorization page and the form

1119
00:44:08,750 --> 00:44:13,640
submission endpoint would have prevented

1120
00:44:10,820 --> 00:44:15,980
this issue changing else - else--if

1121
00:44:13,640 --> 00:44:16,400
request posts to be very explicit and

1122
00:44:15,980 --> 00:44:18,170
ensure that

1123
00:44:16,400 --> 00:44:19,760
head or any other unexpected methods

1124
00:44:18,170 --> 00:44:22,910
would wouldn't be treated as post would

1125
00:44:19,760 --> 00:44:26,000
have worked yeah those are the things

1126
00:44:22,910 --> 00:44:27,529
that came up with um so yeah this is how

1127
00:44:26,000 --> 00:44:29,180
you would do the explicit check you just

1128
00:44:27,529 --> 00:44:30,500
already met kind of mention this but I

1129
00:44:29,180 --> 00:44:32,270
would I would recommend throwing an

1130
00:44:30,500 --> 00:44:34,279
exception if it's if it's not a get or a

1131
00:44:32,270 --> 00:44:35,450
post and just crash the app it's a

1132
00:44:34,279 --> 00:44:40,089
catastrophic case you're not a key

1133
00:44:35,450 --> 00:44:40,089
you're not you don't want to try and

1134
00:44:40,150 --> 00:44:57,680
recover from this that's a good question

1135
00:44:55,369 --> 00:45:00,140
so yes let's look at that let's look at

1136
00:44:57,680 --> 00:45:01,490
the legit case ok so this is the legit

1137
00:45:00,140 --> 00:45:04,220
case so you're saying that basically

1138
00:45:01,490 --> 00:45:05,390
your concern is let's see at the point

1139
00:45:04,220 --> 00:45:08,029
where the user clicks the login button

1140
00:45:05,390 --> 00:45:09,230
and this request goes to github your

1141
00:45:08,029 --> 00:45:10,670
concern is that the cookie wouldn't be

1142
00:45:09,230 --> 00:45:11,270
attached if it was the same site cookie

1143
00:45:10,670 --> 00:45:12,650
right

1144
00:45:11,270 --> 00:45:15,349
you remember same site has two modes

1145
00:45:12,650 --> 00:45:16,910
they were strict and lacks yeah so if

1146
00:45:15,349 --> 00:45:19,039
you were using the strict mode then

1147
00:45:16,910 --> 00:45:21,619
you're correct that because this request

1148
00:45:19,039 --> 00:45:25,460
was so strict basically says I don't

1149
00:45:21,619 --> 00:45:27,200
care what kind of request it is if if

1150
00:45:25,460 --> 00:45:29,420
the user ends up on my site and it came

1151
00:45:27,200 --> 00:45:31,750
from anywhere don't include the cookies

1152
00:45:29,420 --> 00:45:34,819
that's like extreme paranoia mode right

1153
00:45:31,750 --> 00:45:36,559
the lacs mode says if it's a if the

1154
00:45:34,819 --> 00:45:38,630
entire browser is getting navigated to

1155
00:45:36,559 --> 00:45:40,520
the page like the top-level page is

1156
00:45:38,630 --> 00:45:42,109
changing which is what's happening here

1157
00:45:40,520 --> 00:45:43,809
the user clicks the login button and the

1158
00:45:42,109 --> 00:45:46,309
whole browser just goes to github right

1159
00:45:43,809 --> 00:45:49,579
lac says it's okay to touch the cookie

1160
00:45:46,309 --> 00:46:03,500
in that case and that actually means

1161
00:45:49,579 --> 00:46:04,549
that this would work still yeah but

1162
00:46:03,500 --> 00:46:07,720
don't they always throw permission

1163
00:46:04,549 --> 00:46:07,720
probably better understand the question

1164
00:46:17,799 --> 00:46:22,849
oh yeah there is no way to grant

1165
00:46:20,000 --> 00:46:24,650
permission at all without the going to

1166
00:46:22,849 --> 00:46:25,940
it going to a top level Google page yeah

1167
00:46:24,650 --> 00:46:29,349
you're right because the cookie wouldn't

1168
00:46:25,940 --> 00:46:29,349
be included yeah I think you

1169
00:46:29,599 --> 00:46:34,980
okay so let's go back to where we were

1170
00:46:32,849 --> 00:46:36,240
here yeah okay so now let's think about

1171
00:46:34,980 --> 00:46:37,710
ways that rails could have prevented

1172
00:46:36,240 --> 00:46:39,000
this so we talked about how github will

1173
00:46:37,710 --> 00:46:40,230
get up could have done what could the

1174
00:46:39,000 --> 00:46:43,109
framework have done what could they

1175
00:46:40,230 --> 00:46:45,630
design differently to prevent this kind

1176
00:46:43,109 --> 00:46:47,880
of an issue I feel like they kind of

1177
00:46:45,630 --> 00:47:15,150
laid a trap for their for their users in

1178
00:46:47,880 --> 00:47:18,720
a way the ideas Oh interesting

1179
00:47:15,150 --> 00:47:22,980
so so if you did a token check for head

1180
00:47:18,720 --> 00:47:24,780
requests that means that that would mean

1181
00:47:22,980 --> 00:47:28,740
that that no one could send a head

1182
00:47:24,780 --> 00:47:31,349
request to a URL unless they had first

1183
00:47:28,740 --> 00:47:34,440
loaded a different URL and gotten a

1184
00:47:31,349 --> 00:47:36,089
token out of that response right so you

1185
00:47:34,440 --> 00:47:38,490
could require that of yourself your

1186
00:47:36,089 --> 00:47:41,400
users but it is changing the semantics a

1187
00:47:38,490 --> 00:47:42,839
little bit so I was like normally I

1188
00:47:41,400 --> 00:47:44,520
could say I could send a head request to

1189
00:47:42,839 --> 00:47:45,570
get the homepage of the site and I don't

1190
00:47:44,520 --> 00:47:48,869
have to know anything about this site I

1191
00:47:45,570 --> 00:47:50,849
can just say give me the homepage and if

1192
00:47:48,869 --> 00:47:53,760
you if you required a CSRF token in that

1193
00:47:50,849 --> 00:47:55,890
case then I would first have to like do

1194
00:47:53,760 --> 00:47:58,109
a get request for the homepage get the

1195
00:47:55,890 --> 00:47:59,490
response find the token include it and

1196
00:47:58,109 --> 00:48:01,200
then send the head which defeats the

1197
00:47:59,490 --> 00:48:03,750
whole point of sending the head right

1198
00:48:01,200 --> 00:48:05,550
yeah but it could work it's just a

1199
00:48:03,750 --> 00:48:07,950
complete different like set of

1200
00:48:05,550 --> 00:48:11,180
assumptions you're making yeah

1201
00:48:07,950 --> 00:48:11,180
[Music]

1202
00:48:25,990 --> 00:48:30,770
yeah so you think that you think

1203
00:48:28,670 --> 00:48:32,180
checking get directly is such an

1204
00:48:30,770 --> 00:48:33,830
uncommon thing that we should just

1205
00:48:32,180 --> 00:48:36,620
discourage it yeah I don't actually

1206
00:48:33,830 --> 00:48:38,060
don't know how common it is I mean from

1207
00:48:36,620 --> 00:48:39,970
my experience writing code in a note and

1208
00:48:38,060 --> 00:48:43,090
Express I do sometimes check the method

1209
00:48:39,970 --> 00:48:45,110
like for legit reasons so I would be

1210
00:48:43,090 --> 00:48:47,120
maybe a little bit annoyed if I had to

1211
00:48:45,110 --> 00:48:49,640
always be like writing in all caps or

1212
00:48:47,120 --> 00:48:51,230
something to like do it but it would

1213
00:48:49,640 --> 00:48:53,800
certainly they would have prevented this

1214
00:48:51,230 --> 00:49:08,630
case yeah you're right I agree with you

1215
00:48:53,800 --> 00:49:10,280
yeah did you have another one the

1216
00:49:08,630 --> 00:49:12,500
browser the browser consent head

1217
00:49:10,280 --> 00:49:14,750
requests for like its own reasons like

1218
00:49:12,500 --> 00:49:16,130
for before downloading a file or another

1219
00:49:14,750 --> 00:49:18,200
site can just cause a head request to

1220
00:49:16,130 --> 00:49:41,540
get sense it's similar to get so it can

1221
00:49:18,200 --> 00:49:42,650
just cause it question yeah you have to

1222
00:49:41,540 --> 00:49:45,440
talk after class but I'm not

1223
00:49:42,650 --> 00:49:48,650
understanding the question okay it's I

1224
00:49:45,440 --> 00:49:51,530
will talk about it after class yeah okay

1225
00:49:48,650 --> 00:49:53,870
so I had some ideas for ways rails could

1226
00:49:51,530 --> 00:49:54,920
prevent this so I mean one thing you can

1227
00:49:53,870 --> 00:49:56,960
imagine is just don't handle this

1228
00:49:54,920 --> 00:49:58,490
automatically for the user force them to

1229
00:49:56,960 --> 00:50:00,410
handle head requests themselves that's

1230
00:49:58,490 --> 00:50:01,850
one option I think that if you do this

1231
00:50:00,410 --> 00:50:04,130
then probably no one is going to be

1232
00:50:01,850 --> 00:50:05,960
supporting head requests and their sites

1233
00:50:04,130 --> 00:50:08,840
so you kind of lose lose that benefit

1234
00:50:05,960 --> 00:50:12,350
but that's an option another idea is you

1235
00:50:08,840 --> 00:50:16,280
could set request get to true even if

1236
00:50:12,350 --> 00:50:17,270
it's a head request and this is lying to

1237
00:50:16,280 --> 00:50:18,590
the developer basically the framework

1238
00:50:17,270 --> 00:50:20,120
could lie to the developer and tell them

1239
00:50:18,590 --> 00:50:23,180
it's it's a get request even though it's

1240
00:50:20,120 --> 00:50:26,120
a head request I would argue this is

1241
00:50:23,180 --> 00:50:27,440
actually fine in a way because the

1242
00:50:26,120 --> 00:50:29,360
developer when they wrote this

1243
00:50:27,440 --> 00:50:32,540
controller said I am prepared to handle

1244
00:50:29,360 --> 00:50:34,220
gets and posts in this controller so we

1245
00:50:32,540 --> 00:50:36,140
should assume their code is only going

1246
00:50:34,220 --> 00:50:37,160
to be checking forgets and posts so

1247
00:50:36,140 --> 00:50:39,920
sending them head

1248
00:50:37,160 --> 00:50:41,260
kind of a violation of the abstraction

1249
00:50:39,920 --> 00:50:43,549
that we've created here it's like

1250
00:50:41,260 --> 00:50:44,660
leaking out some random implementation

1251
00:50:43,549 --> 00:50:46,940
details that we don't want to leak out

1252
00:50:44,660 --> 00:50:50,210
so if instead pretended that the head

1253
00:50:46,940 --> 00:50:51,589
was a get then the now the we know the

1254
00:50:50,210 --> 00:50:53,299
developers code is gonna run correctly

1255
00:50:51,589 --> 00:50:54,829
because we're only giving it gets and

1256
00:50:53,299 --> 00:50:57,200
posts like we act like they asked for

1257
00:50:54,829 --> 00:50:58,640
right and then after we sort of get the

1258
00:50:57,200 --> 00:51:00,049
response we could then delete the body

1259
00:50:58,640 --> 00:51:02,390
and handle it for them and now the

1260
00:51:00,049 --> 00:51:03,680
abstraction isn't leaky right it's just

1261
00:51:02,390 --> 00:51:04,819
this do people know what I mean when I

1262
00:51:03,680 --> 00:51:07,099
say leaky abstraction who's heard that

1263
00:51:04,819 --> 00:51:12,950
term before who doesn't who doesn't know

1264
00:51:07,099 --> 00:51:14,089
I can explain okay so the idea of the

1265
00:51:12,950 --> 00:51:15,079
reason why we make abstractions is

1266
00:51:14,089 --> 00:51:17,510
because we're trying to hide some

1267
00:51:15,079 --> 00:51:19,549
complexity away from from the developer

1268
00:51:17,510 --> 00:51:20,900
we're trying to simplify the amount of

1269
00:51:19,549 --> 00:51:25,309
state they have to have in their head in

1270
00:51:20,900 --> 00:51:26,750
order to program something it's like the

1271
00:51:25,309 --> 00:51:27,859
less sort of complexity that they need

1272
00:51:26,750 --> 00:51:30,140
to keep in mind the more likely they are

1273
00:51:27,859 --> 00:51:32,690
to write correct code and so ideally

1274
00:51:30,140 --> 00:51:35,000
abstractions they eliminate unnecessary

1275
00:51:32,690 --> 00:51:38,420
complexity and they only expose the very

1276
00:51:35,000 --> 00:51:40,099
essential complexity that you that like

1277
00:51:38,420 --> 00:51:42,500
you can you can hide too much you can be

1278
00:51:40,099 --> 00:51:44,029
like you know you can have a class which

1279
00:51:42,500 --> 00:51:45,710
or a library which just is has one

1280
00:51:44,029 --> 00:51:47,329
function it's like do the thing right

1281
00:51:45,710 --> 00:51:48,920
and then well that doesn't let you

1282
00:51:47,329 --> 00:51:50,690
configure anything how what if I want to

1283
00:51:48,920 --> 00:51:52,190
do the thing differently like there's no

1284
00:51:50,690 --> 00:51:53,480
options - so you want to expose some

1285
00:51:52,190 --> 00:51:57,109
complexity but you don't want to don't

1286
00:51:53,480 --> 00:51:59,329
want to to expose any sort of extra

1287
00:51:57,109 --> 00:52:00,440
complexity that doesn't is irrelevant

1288
00:51:59,329 --> 00:52:02,119
for the developer to solve the problem

1289
00:52:00,440 --> 00:52:04,460
that they're trying to solve and so a

1290
00:52:02,119 --> 00:52:06,170
leaky abstraction is one where it like

1291
00:52:04,460 --> 00:52:08,150
mostly works it mostly hides the

1292
00:52:06,170 --> 00:52:10,970
unnecessary stuff away but then in some

1293
00:52:08,150 --> 00:52:15,020
places like bits of the implementation

1294
00:52:10,970 --> 00:52:16,789
or bits of details at the developer

1295
00:52:15,020 --> 00:52:20,779
ideally wouldn't even need to know about

1296
00:52:16,789 --> 00:52:22,579
leak out in in small ways and then

1297
00:52:20,779 --> 00:52:24,049
violate that I was like break the

1298
00:52:22,579 --> 00:52:25,430
abstraction make it less make it a less

1299
00:52:24,049 --> 00:52:26,390
useful abstraction because now that

1300
00:52:25,430 --> 00:52:28,190
developer has to keep these edge cases

1301
00:52:26,390 --> 00:52:29,690
in their head in order to use it

1302
00:52:28,190 --> 00:52:31,940
correctly like that's what happened here

1303
00:52:29,690 --> 00:52:33,589
like this abstraction was like oh it's

1304
00:52:31,940 --> 00:52:34,579
just you know we're gonna we're gonna do

1305
00:52:33,589 --> 00:52:35,869
this clever thing that the developer

1306
00:52:34,579 --> 00:52:37,760
won't need to think about and then

1307
00:52:35,869 --> 00:52:38,599
whoops actually they need to know about

1308
00:52:37,760 --> 00:52:39,650
it they need to know about ahead

1309
00:52:38,599 --> 00:52:41,569
requests so you didn't actually make

1310
00:52:39,650 --> 00:52:44,359
their life simpler in fact you you just

1311
00:52:41,569 --> 00:52:47,270
cost them 25k and potentially a lot of

1312
00:52:44,359 --> 00:52:49,970
you know user data lost so yeah that's

1313
00:52:47,270 --> 00:52:51,080
that's leaky abstraction okay so another

1314
00:52:49,970 --> 00:52:53,480
idea

1315
00:52:51,080 --> 00:52:55,400
right okay so yeah basically yeah I

1316
00:52:53,480 --> 00:52:57,380
already mentioned this and then here's a

1317
00:52:55,400 --> 00:52:58,940
crazy idea you could use a more strongly

1318
00:52:57,380 --> 00:53:01,490
typed language like Haskell or something

1319
00:52:58,940 --> 00:53:02,450
it's a part of the reason why I mean you

1320
00:53:01,490 --> 00:53:04,280
could argue part of the reason why this

1321
00:53:02,450 --> 00:53:06,890
issue happened is because there was no

1322
00:53:04,280 --> 00:53:09,760
way to enforce that every case that

1323
00:53:06,890 --> 00:53:11,870
could possibly get given to this

1324
00:53:09,760 --> 00:53:13,130
developer's code where there was no way

1325
00:53:11,870 --> 00:53:15,230
to enforce that the handle each of those

1326
00:53:13,130 --> 00:53:16,730
cases in a more strongly typed language

1327
00:53:15,230 --> 00:53:20,030
you could actually have a compiler error

1328
00:53:16,730 --> 00:53:21,590
if they only said case get case post and

1329
00:53:20,030 --> 00:53:24,170
they forgot one of the cases that you

1330
00:53:21,590 --> 00:53:26,660
might call their code with this slows

1331
00:53:24,170 --> 00:53:28,810
down like development arguably a lot and

1332
00:53:26,660 --> 00:53:31,940
you know people don't like it and people

1333
00:53:28,810 --> 00:53:33,650
people usually use these these looser

1334
00:53:31,940 --> 00:53:46,640
languages for a reason but that is one

1335
00:53:33,650 --> 00:53:48,080
solution yeah Oh like I say like like

1336
00:53:46,640 --> 00:53:48,590
look at the function and see if it's

1337
00:53:48,080 --> 00:53:50,780
English

1338
00:53:48,590 --> 00:53:52,340
I mean in Ruby I guess you could that it

1339
00:53:50,780 --> 00:53:54,020
might have some kind of introspection I

1340
00:53:52,340 --> 00:53:56,390
know in JavaScript you can literally to

1341
00:53:54,020 --> 00:53:57,290
string the function and then then you

1342
00:53:56,390 --> 00:53:58,640
have a string version of the function

1343
00:53:57,290 --> 00:54:00,800
and then you could parse it yourself

1344
00:53:58,640 --> 00:54:04,850
with your own JavaScript parser and see

1345
00:54:00,800 --> 00:54:06,980
if it actually you know accesses request

1346
00:54:04,850 --> 00:54:10,790
dot head or something like that I don't

1347
00:54:06,980 --> 00:54:12,380
recommend that there may be yeah I mean

1348
00:54:10,790 --> 00:54:13,670
other than that grouse approach I can't

1349
00:54:12,380 --> 00:54:21,440
think of a way to serve in advance know

1350
00:54:13,670 --> 00:54:24,470
that it's going to handle it yeah okay

1351
00:54:21,440 --> 00:54:26,540
so so some lessons that I think we've

1352
00:54:24,470 --> 00:54:27,770
based on the different possible

1353
00:54:26,540 --> 00:54:28,730
solutions that we've proposed I think

1354
00:54:27,770 --> 00:54:31,070
there's some lessons we can sort of

1355
00:54:28,730 --> 00:54:33,380
glean for how to how to sort of prevent

1356
00:54:31,070 --> 00:54:36,380
these kinds of problems in our code or

1357
00:54:33,380 --> 00:54:37,700
in our libraries that we write one big

1358
00:54:36,380 --> 00:54:41,060
common theme that you'll see all the

1359
00:54:37,700 --> 00:54:43,040
time in security context is that we want

1360
00:54:41,060 --> 00:54:46,190
to try to reduce complexity complexity

1361
00:54:43,040 --> 00:54:52,580
is the source of so many security issues

1362
00:54:46,190 --> 00:54:53,810
and when we have abstractions that we're

1363
00:54:52,580 --> 00:54:58,400
trying to hide complexity from the

1364
00:54:53,810 --> 00:54:59,870
developer and and and so yeah I guess I

1365
00:54:58,400 --> 00:55:01,400
already said this the more edge cases

1366
00:54:59,870 --> 00:55:04,340
that an abstraction has the leakier that

1367
00:55:01,400 --> 00:55:04,920
it is so the more complexity you have

1368
00:55:04,340 --> 00:55:06,270
they also have

1369
00:55:04,920 --> 00:55:07,950
more sort of interactions between

1370
00:55:06,270 --> 00:55:09,270
different components in a system and as

1371
00:55:07,950 --> 00:55:13,110
sort of you get like this multiplicative

1372
00:55:09,270 --> 00:55:14,340
effect where like if you introduce a new

1373
00:55:13,110 --> 00:55:15,900
component you might think I'm just

1374
00:55:14,340 --> 00:55:18,180
adding one thing to this system right

1375
00:55:15,900 --> 00:55:19,590
but if the question is not how many

1376
00:55:18,180 --> 00:55:20,850
things that I add to the system the

1377
00:55:19,590 --> 00:55:22,650
question is how many things did the

1378
00:55:20,850 --> 00:55:24,960
thing I just add how many things cannot

1379
00:55:22,650 --> 00:55:28,260
interact with in the system the system

1380
00:55:24,960 --> 00:55:29,370
has 500 other components and I added

1381
00:55:28,260 --> 00:55:31,230
this one in a way that it could

1382
00:55:29,370 --> 00:55:33,570
potentially interact with any of the 500

1383
00:55:31,230 --> 00:55:35,820
right then I've actually it's not it's a

1384
00:55:33,570 --> 00:55:37,200
much sort of scary or change then

1385
00:55:35,820 --> 00:55:38,280
something that I just added in a very

1386
00:55:37,200 --> 00:55:40,380
isolated way and I know it's only

1387
00:55:38,280 --> 00:55:42,320
talking to this one other thing so

1388
00:55:40,380 --> 00:55:45,600
complexity can come from like lots of

1389
00:55:42,320 --> 00:55:48,390
places and it's usually the enemy of

1390
00:55:45,600 --> 00:55:52,350
security also explicit code is better

1391
00:55:48,390 --> 00:55:53,370
than clever code so I think this is the

1392
00:55:52,350 --> 00:55:54,810
kind of thing that you get you get

1393
00:55:53,370 --> 00:55:56,070
better at over time in your career at

1394
00:55:54,810 --> 00:55:59,520
least that's how it's been for me where

1395
00:55:56,070 --> 00:56:00,780
um like at first it's really fun and

1396
00:55:59,520 --> 00:56:01,980
exciting to like try to like write like

1397
00:56:00,780 --> 00:56:03,270
a really clever one-liner and like I

1398
00:56:01,980 --> 00:56:04,440
look at all the functionality I packed

1399
00:56:03,270 --> 00:56:05,490
into this line like I'm such a good

1400
00:56:04,440 --> 00:56:07,460
coder I'm gonna impress all my

1401
00:56:05,490 --> 00:56:09,120
co-workers and my classmates like

1402
00:56:07,460 --> 00:56:09,960
because they're gonna look at it they're

1403
00:56:09,120 --> 00:56:13,890
not even gonna know what it's doing

1404
00:56:09,960 --> 00:56:15,690
aren't I so I'm so cool right I must be

1405
00:56:13,890 --> 00:56:19,800
more you know elite than everybody else

1406
00:56:15,690 --> 00:56:21,180
and as you go through your career and

1407
00:56:19,800 --> 00:56:23,370
then you come back to code and you're

1408
00:56:21,180 --> 00:56:24,630
like this is terrible who wrote this and

1409
00:56:23,370 --> 00:56:26,250
then you look at the get history and you

1410
00:56:24,630 --> 00:56:28,440
realize you wrote it and you were too

1411
00:56:26,250 --> 00:56:30,090
clever so that literally your self can't

1412
00:56:28,440 --> 00:56:31,860
understand it like a month later then

1413
00:56:30,090 --> 00:56:34,260
you serve after this bites you enough

1414
00:56:31,860 --> 00:56:36,840
times you just start saying like okay no

1415
00:56:34,260 --> 00:56:38,850
no no I'm just gonna unroll this code

1416
00:56:36,840 --> 00:56:40,590
and make it much more verbose and much

1417
00:56:38,850 --> 00:56:41,910
more like dumb you know just much

1418
00:56:40,590 --> 00:56:43,920
simpler it's gonna do this then this

1419
00:56:41,910 --> 00:56:47,700
then this and it's gonna look uglier but

1420
00:56:43,920 --> 00:56:50,150
it's gonna be understandable so yeah I

1421
00:56:47,700 --> 00:56:54,630
think I don't know just the thing that I

1422
00:56:50,150 --> 00:56:56,490
think most people tend to write less

1423
00:56:54,630 --> 00:57:02,820
clever code as as their career goes on

1424
00:56:56,490 --> 00:57:04,170
that's what I've noticed yeah and then

1425
00:57:02,820 --> 00:57:07,800
the other another idea is to fail early

1426
00:57:04,170 --> 00:57:10,290
so if an assumption that you have is I

1427
00:57:07,800 --> 00:57:12,390
guess this is mixing it to up fail early

1428
00:57:10,290 --> 00:57:14,340
the idea is basically if something is in

1429
00:57:12,390 --> 00:57:17,430
a state that you don't expect it to be

1430
00:57:14,340 --> 00:57:18,930
in then just crash or throw an exception

1431
00:57:17,430 --> 00:57:22,470
don't try to like

1432
00:57:18,930 --> 00:57:27,660
go onward don't don't try to to handle

1433
00:57:22,470 --> 00:57:30,000
it and like one example where this comes

1434
00:57:27,660 --> 00:57:31,549
up is you can you can attack you can do

1435
00:57:30,000 --> 00:57:33,900
this thing in nodejs where you can say

1436
00:57:31,549 --> 00:57:35,819
when an uncaught exception happens in my

1437
00:57:33,900 --> 00:57:37,799
program I want this function to run to

1438
00:57:35,819 --> 00:57:40,020
handle it and so what you can do is you

1439
00:57:37,799 --> 00:57:42,299
can sort of say I a handle it sort of

1440
00:57:40,020 --> 00:57:44,339
like a top-level try-catch you're like

1441
00:57:42,299 --> 00:57:45,869
any exception anywhere just go like if

1442
00:57:44,339 --> 00:57:47,700
it's not handled at a lower level I

1443
00:57:45,869 --> 00:57:49,440
wanted to run this function and what

1444
00:57:47,700 --> 00:57:52,230
people used to do is they would just log

1445
00:57:49,440 --> 00:57:54,089
out the error and then not crash the

1446
00:57:52,230 --> 00:57:56,450
process they would just keep it running

1447
00:57:54,089 --> 00:57:58,680
right an idea is like oh well you know

1448
00:57:56,450 --> 00:58:00,029
like it's probably fine like maybe that

1449
00:57:58,680 --> 00:58:01,170
would that was an exception that wasn't

1450
00:58:00,029 --> 00:58:02,160
a big deal like it was let me just log

1451
00:58:01,170 --> 00:58:04,349
it I'll fix it later

1452
00:58:02,160 --> 00:58:05,819
keep the process running problem is you

1453
00:58:04,349 --> 00:58:07,859
don't know where the error happened you

1454
00:58:05,819 --> 00:58:09,270
don't know what like multi-step process

1455
00:58:07,859 --> 00:58:10,440
you were in the middle of and you threw

1456
00:58:09,270 --> 00:58:11,730
an exception in the middle of it and now

1457
00:58:10,440 --> 00:58:13,230
some state that you set up and we're

1458
00:58:11,730 --> 00:58:14,309
expecting to get cleaned up later you

1459
00:58:13,230 --> 00:58:15,809
didn't you're not gonna get around to

1460
00:58:14,309 --> 00:58:17,910
doing that now because you bailed out

1461
00:58:15,809 --> 00:58:22,049
halfway through so rather than try to

1462
00:58:17,910 --> 00:58:23,730
resume sorry rather than assuming it's

1463
00:58:22,049 --> 00:58:24,869
fine to keep going you should just crash

1464
00:58:23,730 --> 00:58:28,529
the whole process because you don't know

1465
00:58:24,869 --> 00:58:29,849
what state it's in now and so crash the

1466
00:58:28,529 --> 00:58:32,039
process and then usually you have some

1467
00:58:29,849 --> 00:58:33,630
other process on the system that will

1468
00:58:32,039 --> 00:58:35,910
just reboot the node process or whatever

1469
00:58:33,630 --> 00:58:38,069
server process and start it from scratch

1470
00:58:35,910 --> 00:58:40,680
and you can if you have more than one of

1471
00:58:38,069 --> 00:58:44,309
these you can handle handle crashes

1472
00:58:40,680 --> 00:58:46,529
without any downtime for your users yeah

1473
00:58:44,309 --> 00:58:48,299
so that's it's a good idea and then

1474
00:58:46,529 --> 00:58:49,640
lastly code defensively so assume your

1475
00:58:48,299 --> 00:58:54,630
assumptions are going to be violated and

1476
00:58:49,640 --> 00:58:55,859
verify them upfront and and don't assume

1477
00:58:54,630 --> 00:58:56,970
that your function is going to be called

1478
00:58:55,859 --> 00:59:00,900
with the correct arguments for example

1479
00:58:56,970 --> 00:59:04,140
right it might not be so any questions

1480
00:59:00,900 --> 00:59:05,490
about these lessons didn't make sense to

1481
00:59:04,140 --> 00:59:06,329
people if you just you can disagree if

1482
00:59:05,490 --> 00:59:08,430
you want I mean they're they're not

1483
00:59:06,329 --> 00:59:10,319
they're not like hard and fast rules

1484
00:59:08,430 --> 00:59:11,400
it's a lot of it is taste and just like

1485
00:59:10,319 --> 00:59:13,849
trade-offs

1486
00:59:11,400 --> 00:59:17,480
everything is trade-offs but these are

1487
00:59:13,849 --> 00:59:17,480
some things that I think are useful

1488
00:59:17,539 --> 00:59:20,539
mm-hmm

1489
00:59:21,720 --> 00:59:31,500
I guess yeah

1490
00:59:26,970 --> 00:59:33,180
that's true yeah we call that security

1491
00:59:31,500 --> 00:59:36,680
through obscurity though and we don't

1492
00:59:33,180 --> 00:59:39,810
encourage it yeah

1493
00:59:36,680 --> 00:59:41,430
okay so I'll skip this I was just gonna

1494
00:59:39,810 --> 00:59:43,400
this is gonna go through the sort of the

1495
00:59:41,430 --> 00:59:45,330
things we talked about and try to

1496
00:59:43,400 --> 00:59:49,440
associate them with each of the lessons

1497
00:59:45,330 --> 00:59:51,510
but I think that's not necessary okay so

1498
00:59:49,440 --> 01:00:01,740
yeah the next thing I wanted to oh yeah

1499
00:59:51,510 --> 01:00:03,869
question hmm yeah so so that's a really

1500
01:00:01,740 --> 01:00:07,410
good question so I guess yeah what I

1501
01:00:03,869 --> 01:00:09,410
said before is is not complete so if the

1502
01:00:07,410 --> 01:00:13,320
error that happened is expected like you

1503
01:00:09,410 --> 01:00:14,940
say here's an example I'm going to make

1504
01:00:13,320 --> 01:00:18,240
a query to the database for a particular

1505
01:00:14,940 --> 01:00:20,550
user with a certain ID number right and

1506
01:00:18,240 --> 01:00:23,760
then I may get a user back I mean not

1507
01:00:20,550 --> 01:00:25,560
because maybe that ID doesn't exist as a

1508
01:00:23,760 --> 01:00:27,270
developer I'm actually expecting that

1509
01:00:25,560 --> 01:00:28,619
this may fail sometimes because say that

1510
01:00:27,270 --> 01:00:30,119
the ID number that I'm looking up is

1511
01:00:28,619 --> 01:00:32,700
provided by the user the user goes to

1512
01:00:30,119 --> 01:00:34,410
some URL you know slash users slash 25

1513
01:00:32,700 --> 01:00:36,349
that could be you know the user could

1514
01:00:34,410 --> 01:00:39,330
type in a tight make a typo and go to a

1515
01:00:36,349 --> 01:00:41,220
URL where that user ID doesn't exist so

1516
01:00:39,330 --> 01:00:45,660
if I'm writing code to go get that user

1517
01:00:41,220 --> 01:00:46,859
out of the database and and the idea I'm

1518
01:00:45,660 --> 01:00:48,810
looking up is provided by the user

1519
01:00:46,859 --> 01:00:50,970
well that user might not exist so I

1520
01:00:48,810 --> 01:00:52,440
should in my code expect that that may

1521
01:00:50,970 --> 01:00:54,540
return an error to me and say there's no

1522
01:00:52,440 --> 01:00:57,119
user with that ID in that in that case

1523
01:00:54,540 --> 01:01:00,060
because I was expecting that error it's

1524
01:00:57,119 --> 01:01:01,650
totally fine for for me to return like

1525
01:01:00,060 --> 01:01:03,660
return an error code to the user give

1526
01:01:01,650 --> 01:01:05,609
him a 404 error and say no one with that

1527
01:01:03,660 --> 01:01:07,109
idea exists and to keep the server

1528
01:01:05,609 --> 01:01:08,369
running I shouldn't crash you shouldn't

1529
01:01:07,109 --> 01:01:09,660
crash the server in that case because I

1530
01:01:08,369 --> 01:01:12,030
was an error you were expecting and you

1531
01:01:09,660 --> 01:01:14,250
wrote code to handle it right and and um

1532
01:01:12,030 --> 01:01:16,560
the difference between that and what I

1533
01:01:14,250 --> 01:01:18,300
was talking about before is if an

1534
01:01:16,560 --> 01:01:23,520
exception happens and you didn't expect

1535
01:01:18,300 --> 01:01:25,830
it to happen it's not appropriate to to

1536
01:01:23,520 --> 01:01:29,099
just like log that out and then keep

1537
01:01:25,830 --> 01:01:30,900
going because it could anything could

1538
01:01:29,099 --> 01:01:32,310
have gone wrong you don't know what you

1539
01:01:30,900 --> 01:01:33,960
weren't you actually did no code to sort

1540
01:01:32,310 --> 01:01:35,460
of clean up and handle that exception

1541
01:01:33,960 --> 01:01:38,100
you weren't expecting it

1542
01:01:35,460 --> 01:01:45,660
right does this thing should make some

1543
01:01:38,100 --> 01:01:48,510
sense okay cool cool okay so yeah so

1544
01:01:45,660 --> 01:01:52,410
let's talk about the next topic which is

1545
01:01:48,510 --> 01:01:55,650
bad API design so this is a fun one

1546
01:01:52,410 --> 01:01:59,040
so the idea what this is just that

1547
01:01:55,650 --> 01:02:00,000
there's there's so we mention all these

1548
01:01:59,040 --> 01:02:03,300
different ways that we could we could

1549
01:02:00,000 --> 01:02:04,740
try to write better code clean code and

1550
01:02:03,300 --> 01:02:06,090
avoid you know tricking ourselves and

1551
01:02:04,740 --> 01:02:08,520
being defensive and all this stuff

1552
01:02:06,090 --> 01:02:10,320
um but sometimes an API that you're

1553
01:02:08,520 --> 01:02:13,760
using is just badly designed and it's

1554
01:02:10,320 --> 01:02:16,260
set up in a way that is likely to

1555
01:02:13,760 --> 01:02:18,240
mislead you right some ways this can

1556
01:02:16,260 --> 01:02:21,870
happen is say that the default

1557
01:02:18,240 --> 01:02:24,990
parameters that the function they're

1558
01:02:21,870 --> 01:02:26,370
calling assumes are insecure and the

1559
01:02:24,990 --> 01:02:27,600
only way to use this function securely

1560
01:02:26,370 --> 01:02:29,460
is to actually pass in a bunch of

1561
01:02:27,600 --> 01:02:33,180
options to make it work the way you want

1562
01:02:29,460 --> 01:02:35,070
I would argue this is like this is bad

1563
01:02:33,180 --> 01:02:36,420
because most users if you know they're

1564
01:02:35,070 --> 01:02:37,680
gonna just call it without any options

1565
01:02:36,420 --> 01:02:39,300
and then they're going to be running it

1566
01:02:37,680 --> 01:02:41,370
in an unsafe way and so we want the

1567
01:02:39,300 --> 01:02:44,160
defaults to be secure we want the

1568
01:02:41,370 --> 01:02:46,680
defaults to be reasonable and so this is

1569
01:02:44,160 --> 01:02:47,760
one way that an API can be can be poorly

1570
01:02:46,680 --> 01:02:49,260
designed you'll notice that it's

1571
01:02:47,760 --> 01:02:50,610
possible to use it correctly you might

1572
01:02:49,260 --> 01:02:51,840
actually pass all the correct options

1573
01:02:50,610 --> 01:02:55,140
but you're just encouraging you're

1574
01:02:51,840 --> 01:02:57,330
making the easy path the the unsafe way

1575
01:02:55,140 --> 01:02:58,950
um another thing you'll may see is

1576
01:02:57,330 --> 01:03:03,110
polymorphic function signatures so this

1577
01:02:58,950 --> 01:03:05,480
is where a function takes in multiple

1578
01:03:03,110 --> 01:03:07,680
different types of parameters and

1579
01:03:05,480 --> 01:03:08,820
effectively this one function is doing

1580
01:03:07,680 --> 01:03:11,160
like one or two or three or four

1581
01:03:08,820 --> 01:03:12,780
different things and they're did it the

1582
01:03:11,160 --> 01:03:14,190
way that it decides what which one of

1583
01:03:12,780 --> 01:03:15,510
those things to do is based on the type

1584
01:03:14,190 --> 01:03:16,830
of the parameter like maybe you pass in

1585
01:03:15,510 --> 01:03:19,110
a number it does one thing you pass in a

1586
01:03:16,830 --> 01:03:20,730
string it does something else or if you

1587
01:03:19,110 --> 01:03:23,160
pass in an extra argument it there's a

1588
01:03:20,730 --> 01:03:24,090
completely different thing right you

1589
01:03:23,160 --> 01:03:25,500
don't want to bundle too much

1590
01:03:24,090 --> 01:03:29,520
functionality into one function I are I

1591
01:03:25,500 --> 01:03:30,960
would argue because it's it's harder for

1592
01:03:29,520 --> 01:03:32,790
the user to use correctly and especially

1593
01:03:30,960 --> 01:03:34,320
in a loosely typed language like

1594
01:03:32,790 --> 01:03:36,960
JavaScript well we'll talk about some

1595
01:03:34,320 --> 01:03:38,370
examples and this is a really really

1596
01:03:36,960 --> 01:03:40,620
wild one I've seen this before actually

1597
01:03:38,370 --> 01:03:41,970
expressed as this you can actually have

1598
01:03:40,620 --> 01:03:44,700
functions where they do a different

1599
01:03:41,970 --> 01:03:47,250
thing based on the number of arguments

1600
01:03:44,700 --> 01:03:49,110
in the callback function I'll show an

1601
01:03:47,250 --> 01:03:51,480
example of it it's called function arity

1602
01:03:49,110 --> 01:03:54,630
okay so here's a really common example

1603
01:03:51,480 --> 01:03:56,190
you if you've ever used jQuery this is a

1604
01:03:54,630 --> 01:03:58,800
jQuery is kind of old these days it's

1605
01:03:56,190 --> 01:04:00,990
not cool anymore but it's actually still

1606
01:03:58,800 --> 01:04:03,990
really we're really widely used though

1607
01:04:00,990 --> 01:04:05,820
still growing I think too but anyway it

1608
01:04:03,990 --> 01:04:08,640
has it's it's a very good example of a

1609
01:04:05,820 --> 01:04:10,320
very polymorphic function so depending

1610
01:04:08,640 --> 01:04:11,580
on what you pass in the type of what you

1611
01:04:10,320 --> 01:04:13,500
pass in it does a completely different

1612
01:04:11,580 --> 01:04:15,570
thing so if you pass in a string that is

1613
01:04:13,500 --> 01:04:17,010
happens to be a CSS selector to select

1614
01:04:15,570 --> 01:04:20,820
an element on the page like in this case

1615
01:04:17,010 --> 01:04:22,290
button then this will return you the it

1616
01:04:20,820 --> 01:04:24,180
will return you a jQuery object that

1617
01:04:22,290 --> 01:04:26,520
wraps that Dom node that matches that

1618
01:04:24,180 --> 01:04:28,760
right actually it could be it could also

1619
01:04:26,520 --> 01:04:30,930
return you an array of like multiple

1620
01:04:28,760 --> 01:04:34,020
nodes if there's multiple buttons on the

1621
01:04:30,930 --> 01:04:35,310
page you can also pass in an HTML

1622
01:04:34,020 --> 01:04:38,340
element and then it will wrap it with

1623
01:04:35,310 --> 01:04:39,810
the jquery wrapper you can pass in

1624
01:04:38,340 --> 01:04:42,480
another jquery object and then it clones

1625
01:04:39,810 --> 01:04:45,270
it so that's this is a copy operation or

1626
01:04:42,480 --> 01:04:46,740
you can pass in some HTML and then it

1627
01:04:45,270 --> 01:04:48,990
will parse the HTML and create a Dom

1628
01:04:46,740 --> 01:04:50,640
node with that HTML inside it you'll

1629
01:04:48,990 --> 01:04:52,860
notice here this is really wild one

1630
01:04:50,640 --> 01:04:54,900
because this is actually a string and

1631
01:04:52,860 --> 01:04:56,610
that's also up there a string so we're

1632
01:04:54,900 --> 01:04:58,110
actually doing two different things even

1633
01:04:56,610 --> 01:04:59,670
though it's exactly the same function

1634
01:04:58,110 --> 01:05:01,140
prototype we're actually deciding

1635
01:04:59,670 --> 01:05:02,430
whether it looks like HTML to us or not

1636
01:05:01,140 --> 01:05:04,380
and doing a different thing that's

1637
01:05:02,430 --> 01:05:06,270
pretty wild

1638
01:05:04,380 --> 01:05:08,940
also happens to be really insecure in

1639
01:05:06,270 --> 01:05:10,680
practice and then the other last case is

1640
01:05:08,940 --> 01:05:11,880
you can pass in a function and then what

1641
01:05:10,680 --> 01:05:13,380
this does is this actually runs this

1642
01:05:11,880 --> 01:05:15,930
function when the whole page is finished

1643
01:05:13,380 --> 01:05:17,730
loading so they've met packed all this

1644
01:05:15,930 --> 01:05:21,060
behavior into this like one dollar sign

1645
01:05:17,730 --> 01:05:22,260
function and it's it's handy for

1646
01:05:21,060 --> 01:05:23,820
prototyping stuff I mean it's really

1647
01:05:22,260 --> 01:05:24,900
fast it's like that one letter to type

1648
01:05:23,820 --> 01:05:27,420
it's a dollar sign you know it's like

1649
01:05:24,900 --> 01:05:28,920
convenient but it's doing like five

1650
01:05:27,420 --> 01:05:30,960
different things depending on what you

1651
01:05:28,920 --> 01:05:36,690
pass it this is what I'm talking about I

1652
01:05:30,960 --> 01:05:38,070
say polymorphic functions so oh yeah

1653
01:05:36,690 --> 01:05:39,780
here's the here's the Express case I was

1654
01:05:38,070 --> 01:05:42,870
talking about so this is really wild so

1655
01:05:39,780 --> 01:05:44,550
um so this is a middleware a middleware

1656
01:05:42,870 --> 01:05:46,770
is I guess I haven't explained this yet

1657
01:05:44,550 --> 01:05:49,740
in the course but basically we've been

1658
01:05:46,770 --> 01:05:51,180
using app get an app dot post and then

1659
01:05:49,740 --> 01:05:53,100
having these functions that run to sort

1660
01:05:51,180 --> 01:05:55,350
of handle a get or a post to a

1661
01:05:53,100 --> 01:05:56,820
particular URL there's this thing called

1662
01:05:55,350 --> 01:05:59,250
a middleware which is sort of a more

1663
01:05:56,820 --> 01:06:00,510
generalized version of that where what

1664
01:05:59,250 --> 01:06:02,460
we're saying here is just call this

1665
01:06:00,510 --> 01:06:04,650
function for every single request

1666
01:06:02,460 --> 01:06:06,900
yet posts head all of them all the

1667
01:06:04,650 --> 01:06:08,609
methods and all the URLs just always

1668
01:06:06,900 --> 01:06:09,720
call this function and this is actually

1669
01:06:08,609 --> 01:06:11,670
where you would do your CSRF token

1670
01:06:09,720 --> 01:06:13,109
validation as an example right you would

1671
01:06:11,670 --> 01:06:18,750
check if it's post and then do your

1672
01:06:13,109 --> 01:06:19,950
validation or whatever um and what's

1673
01:06:18,750 --> 01:06:21,750
really useful about this too is you can

1674
01:06:19,950 --> 01:06:23,910
call next if you don't want to actually

1675
01:06:21,750 --> 01:06:24,900
handle the request here so typically

1676
01:06:23,910 --> 01:06:28,500
what what would the way these

1677
01:06:24,900 --> 01:06:29,819
middlewares are used is you'll you'll do

1678
01:06:28,500 --> 01:06:31,319
some logging you will do some useful

1679
01:06:29,819 --> 01:06:33,420
operation and you'll call next and then

1680
01:06:31,319 --> 01:06:35,430
eventually your your different handler

1681
01:06:33,420 --> 01:06:38,450
will get run like yet or a post for a

1682
01:06:35,430 --> 01:06:40,140
different URL path am i confusing people

1683
01:06:38,450 --> 01:06:41,910
basically this is the way to run a

1684
01:06:40,140 --> 01:06:44,339
function before every request it really

1685
01:06:41,910 --> 01:06:48,059
is a way to do that but if you pass in a

1686
01:06:44,339 --> 01:06:49,859
fourth argument to the function then

1687
01:06:48,059 --> 01:06:51,420
this is a completely different thing it

1688
01:06:49,859 --> 01:06:54,150
then becomes an air handling middleware

1689
01:06:51,420 --> 01:06:56,339
and what this does is if an exception is

1690
01:06:54,150 --> 01:06:59,339
thrown in any of your handlers for any

1691
01:06:56,339 --> 01:07:02,309
URL that you handle then express looks

1692
01:06:59,339 --> 01:07:04,140
for the first time you call the app dot

1693
01:07:02,309 --> 01:07:07,140
use with a for argument function and

1694
01:07:04,140 --> 01:07:10,710
calls that and then that's supposed to

1695
01:07:07,140 --> 01:07:12,720
handle the error right so basically

1696
01:07:10,710 --> 01:07:14,490
reason why this is bad is like in this

1697
01:07:12,720 --> 01:07:15,750
case look I sent back a response to the

1698
01:07:14,490 --> 01:07:19,049
user and I didn't even use the error

1699
01:07:15,750 --> 01:07:20,700
object right so maybe maybe a developer

1700
01:07:19,049 --> 01:07:22,109
who's going through the code base will

1701
01:07:20,700 --> 01:07:24,799
look at this function and be like wait a

1702
01:07:22,109 --> 01:07:26,730
minute next isn't used error isn't used

1703
01:07:24,799 --> 01:07:28,099
maybe it will just delete these these

1704
01:07:26,730 --> 01:07:30,900
arguments because they're not used right

1705
01:07:28,099 --> 01:07:32,099
so you delete them and then now you've

1706
01:07:30,900 --> 01:07:34,290
changed this from an error handling

1707
01:07:32,099 --> 01:07:35,609
middleware to a normal male where so

1708
01:07:34,290 --> 01:07:38,010
literally the unused argument is

1709
01:07:35,609 --> 01:07:39,839
important here to get expressed to treat

1710
01:07:38,010 --> 01:07:42,089
this as an error handling middleware so

1711
01:07:39,839 --> 01:07:43,799
let's just just a overly fancy API

1712
01:07:42,089 --> 01:07:46,079
design it's bad they should have just

1713
01:07:43,799 --> 01:07:48,720
made it explicit I opened an issue about

1714
01:07:46,079 --> 01:07:50,520
it and they want to fix it but it's they

1715
01:07:48,720 --> 01:07:54,319
haven't done it it's been like years so

1716
01:07:50,520 --> 01:07:57,000
yeah yeah anyway um

1717
01:07:54,319 --> 01:07:59,250
okay how much time do we have well we

1718
01:07:57,000 --> 01:08:00,900
might have to get to this next time but

1719
01:07:59,250 --> 01:08:04,799
I'll start it we have ten minutes okay

1720
01:08:00,900 --> 01:08:12,180
so this one's really cool so this is

1721
01:08:04,799 --> 01:08:15,190
something I worked on so it's it's a I'm

1722
01:08:12,180 --> 01:08:16,300
personally invested in it I guess so

1723
01:08:15,190 --> 01:08:18,400
so there's this thing called the buffer

1724
01:08:16,300 --> 01:08:21,700
class in nodejs

1725
01:08:18,400 --> 01:08:24,520
and the idea is it is a server often

1726
01:08:21,700 --> 01:08:26,530
needs to allocate memory all programs

1727
01:08:24,520 --> 01:08:29,200
need to allocate memory for various

1728
01:08:26,530 --> 01:08:30,750
purposes and at the time JavaScript

1729
01:08:29,200 --> 01:08:33,310
didn't have a way to do this natively

1730
01:08:30,750 --> 01:08:36,010
there was no all you had was strings

1731
01:08:33,310 --> 01:08:38,290
basically you couldn't make an arrays

1732
01:08:36,010 --> 01:08:39,400
but you couldn't make like a you can say

1733
01:08:38,290 --> 01:08:40,510
give me a megabyte of memory and I'm

1734
01:08:39,400 --> 01:08:42,610
gonna put whatever I want in that in

1735
01:08:40,510 --> 01:08:45,130
that megabyte of memory right and so

1736
01:08:42,610 --> 01:08:46,720
node introduced buffer later the

1737
01:08:45,130 --> 01:08:48,280
JavaScript language itself eventually

1738
01:08:46,720 --> 01:08:49,570
got native support for this and they

1739
01:08:48,280 --> 01:08:51,310
introduced these other things called

1740
01:08:49,570 --> 01:08:53,680
typed arrays and ray buffers which give

1741
01:08:51,310 --> 01:08:55,870
you the same same functionality and so

1742
01:08:53,680 --> 01:08:57,400
the browser has these and then

1743
01:08:55,870 --> 01:08:59,980
eventually node also got these because

1744
01:08:57,400 --> 01:09:02,050
it's part of the JavaScript language now

1745
01:08:59,980 --> 01:09:03,670
so notice now hazard is redundant it has

1746
01:09:02,050 --> 01:09:06,190
two ways of doing binary data now

1747
01:09:03,670 --> 01:09:09,790
unfortunately but that's just the way it

1748
01:09:06,190 --> 01:09:11,590
is so this is how you use buffer so

1749
01:09:09,790 --> 01:09:13,840
there's a couple ways you can use it one

1750
01:09:11,590 --> 01:09:15,610
is you can pass in an array of bytes of

1751
01:09:13,840 --> 01:09:18,610
byte values and then you get a buffer

1752
01:09:15,610 --> 01:09:20,260
containing like one two and three bytes

1753
01:09:18,610 --> 01:09:22,300
so this is three bytes of memory right

1754
01:09:20,260 --> 01:09:24,520
with with three there's the three bytes

1755
01:09:22,300 --> 01:09:27,490
you can also pass it a string and then

1756
01:09:24,520 --> 01:09:29,170
it will parse this the look at the ASCII

1757
01:09:27,490 --> 01:09:31,390
values and then it will fill the buffer

1758
01:09:29,170 --> 01:09:33,550
with the ASCII values of for each of

1759
01:09:31,390 --> 01:09:34,570
those letters you can give it a number

1760
01:09:33,550 --> 01:09:37,300
and then it will make a buffer that's

1761
01:09:34,570 --> 01:09:39,280
ten long ten bytes long and you can also

1762
01:09:37,300 --> 01:09:41,410
give it another buffer and I'll copy the

1763
01:09:39,280 --> 01:09:42,940
buffer so this is looking a little bit

1764
01:09:41,410 --> 01:09:44,950
like the jQuery API right it's a little

1765
01:09:42,940 --> 01:09:47,500
bit of many many different things you

1766
01:09:44,950 --> 01:09:49,120
can pass into the buffer constructor and

1767
01:09:47,500 --> 01:09:50,260
you get different behavior so this

1768
01:09:49,120 --> 01:09:54,570
should be tricking some alarm bells

1769
01:09:50,260 --> 01:09:56,530
maybe did you have a question okay so

1770
01:09:54,570 --> 01:09:57,880
okay maybe we can end on the demo

1771
01:09:56,530 --> 01:10:00,900
because I have I have a demo and we have

1772
01:09:57,880 --> 01:10:04,000
nine minutes so I think we'll have time

1773
01:10:00,900 --> 01:10:08,470
so I want to show just how can go wrong

1774
01:10:04,000 --> 01:10:12,270
I guess so here we have ignore that

1775
01:10:08,470 --> 01:10:12,270
first bit so here we have a server and

1776
01:10:13,680 --> 01:10:20,140
what we're gonna do is some live coding

1777
01:10:17,410 --> 01:10:21,490
okay so so we just imported Express we

1778
01:10:20,140 --> 01:10:24,760
created an Express app and we're

1779
01:10:21,490 --> 01:10:26,800
listening on port 4000 by the way

1780
01:10:24,760 --> 01:10:28,600
speaking speaking of api's which are not

1781
01:10:26,800 --> 01:10:30,370
safe by default

1782
01:10:28,600 --> 01:10:32,260
you know the list and API that actually

1783
01:10:30,370 --> 01:10:33,790
causes us to listen on port 4000 if you

1784
01:10:32,260 --> 01:10:35,590
don't pass in an IP address as the

1785
01:10:33,790 --> 01:10:38,650
second argument to it then you're

1786
01:10:35,590 --> 01:10:40,840
listening for any connections to your

1787
01:10:38,650 --> 01:10:43,000
computer on port 4000 so what that means

1788
01:10:40,840 --> 01:10:44,770
is like your laptop if I didn't include

1789
01:10:43,000 --> 01:10:46,660
this any of your laptops in this room

1790
01:10:44,770 --> 01:10:48,520
right now if you knew my computer's IP

1791
01:10:46,660 --> 01:10:50,410
address which you could probably find

1792
01:10:48,520 --> 01:10:52,480
because it's just all my Stanford

1793
01:10:50,410 --> 01:10:55,720
Network you could you could connect to

1794
01:10:52,480 --> 01:10:58,390
my server right so really what this is

1795
01:10:55,720 --> 01:11:00,610
doing is it's saying basically only let

1796
01:10:58,390 --> 01:11:02,680
browsers on my same machine that connect

1797
01:11:00,610 --> 01:11:04,810
support 4000 actually connect don't

1798
01:11:02,680 --> 01:11:08,170
listen for connections from the outside

1799
01:11:04,810 --> 01:11:10,000
world basically that's an that's very

1800
01:11:08,170 --> 01:11:11,980
unsafe the fact that that's not the

1801
01:11:10,000 --> 01:11:15,100
default especially cuz I'm trying to

1802
01:11:11,980 --> 01:11:18,310
code in secure servers right now but

1803
01:11:15,100 --> 01:11:20,350
yeah anyway okay so let's let's see what

1804
01:11:18,310 --> 01:11:22,510
we can do here so I'm gonna make an API

1805
01:11:20,350 --> 01:11:26,620
endpoint that just takes a string and

1806
01:11:22,510 --> 01:11:28,600
then converts it to a hex encoding or

1807
01:11:26,620 --> 01:11:30,310
base64 encoding and we're let the user

1808
01:11:28,600 --> 01:11:31,780
specify what they want but basically

1809
01:11:30,310 --> 01:11:34,870
we'll take in some ASCII text and we'll

1810
01:11:31,780 --> 01:11:37,230
convert it to hex or bay 64 so let's

1811
01:11:34,870 --> 01:11:42,160
make an endpoint called a slash API

1812
01:11:37,230 --> 01:11:48,370
slash convert and this is the function

1813
01:11:42,160 --> 01:11:49,540
that will run and so let me make a

1814
01:11:48,370 --> 01:11:52,210
comment so this is the way I want to use

1815
01:11:49,540 --> 01:11:55,630
this I want the user to visit slash API

1816
01:11:52,210 --> 01:11:58,960
slash convert and I want them to pass in

1817
01:11:55,630 --> 01:12:03,550
a data query so it'll look like that

1818
01:11:58,960 --> 01:12:05,950
slash slash question mark data equals

1819
01:12:03,550 --> 01:12:10,510
and then I want them to pass in a JSON

1820
01:12:05,950 --> 01:12:19,540
object so it'll be like JSON will be

1821
01:12:10,510 --> 01:12:20,890
like stir hello and then type hex so if

1822
01:12:19,540 --> 01:12:23,560
they visit this URL then we're gonna

1823
01:12:20,890 --> 01:12:24,880
basically parse this figure out that

1824
01:12:23,560 --> 01:12:30,010
they want us to convert the string hello

1825
01:12:24,880 --> 01:12:31,360
to hex okay okay so so let's do that so

1826
01:12:30,010 --> 01:12:34,120
basically the main thing we need to do

1827
01:12:31,360 --> 01:12:38,080
here is to get the data off of the

1828
01:12:34,120 --> 01:12:41,719
request query object so that gives us

1829
01:12:38,080 --> 01:12:43,309
the that gives us this string right here

1830
01:12:41,719 --> 01:12:45,169
great and then now we want to actually

1831
01:12:43,309 --> 01:12:46,789
parse it as JSON because right now it's

1832
01:12:45,169 --> 01:12:49,610
just a string and I want to turn it into

1833
01:12:46,789 --> 01:12:54,169
a JSON object so I'll call json dot

1834
01:12:49,610 --> 01:12:55,579
parse and now now this data variable is

1835
01:12:54,169 --> 01:12:59,570
literally an object that's gonna have

1836
01:12:55,579 --> 01:13:01,340
two keys stir and type perfect okay so

1837
01:12:59,570 --> 01:13:03,380
and just to be safe here I will I will

1838
01:13:01,340 --> 01:13:06,469
just confirm that this actually worked

1839
01:13:03,380 --> 01:13:08,599
so yeah by the way if this string is not

1840
01:13:06,469 --> 01:13:09,739
valid JSON then this json.parse function

1841
01:13:08,599 --> 01:13:12,130
is going to throw an exception and

1842
01:13:09,739 --> 01:13:14,030
that's okay Express will actually just

1843
01:13:12,130 --> 01:13:15,169
deliver an error to the user in that

1844
01:13:14,030 --> 01:13:16,249
situation so I'm just gonna I'm not even

1845
01:13:15,169 --> 01:13:17,360
gonna try cat I'm not gonna put a

1846
01:13:16,249 --> 01:13:20,150
try-catch around that I'm just gonna let

1847
01:13:17,360 --> 01:13:23,599
it fail if it fails and the user will

1848
01:13:20,150 --> 01:13:24,919
see an error message so great so now if

1849
01:13:23,599 --> 01:13:26,840
we get to this point we actually have an

1850
01:13:24,919 --> 01:13:29,090
object so what I want to do is let's see

1851
01:13:26,840 --> 01:13:30,709
here I'll say if they didn't provide me

1852
01:13:29,090 --> 01:13:34,989
a string then I'm gonna give them an

1853
01:13:30,709 --> 01:13:41,989
error so I'm gonna throw an error

1854
01:13:34,989 --> 01:13:50,780
missing data dot stir all so I only want

1855
01:13:41,989 --> 01:13:53,479
the type to be hex or base64 let's see

1856
01:13:50,780 --> 01:13:57,739
here oh sorry so if it's not hex if it's

1857
01:13:53,479 --> 01:14:00,829
not hex and it's not base 64 and it's

1858
01:13:57,739 --> 01:14:03,919
not oops

1859
01:14:00,829 --> 01:14:07,939
doing this wrong sorry this okay and

1860
01:14:03,919 --> 01:14:10,880
it's not utf-8 which is just a plain

1861
01:14:07,939 --> 01:14:17,749
plain like a normal string then I'm

1862
01:14:10,880 --> 01:14:20,239
gonna throw a new error data dot type is

1863
01:14:17,749 --> 01:14:22,159
invalid okay so now if we get here I

1864
01:14:20,239 --> 01:14:23,150
have an object with these two things and

1865
01:14:22,159 --> 01:14:24,380
I think that they're I think they're in

1866
01:14:23,150 --> 01:14:26,570
the right state so I'm gonna actually go

1867
01:14:24,380 --> 01:14:30,889
ahead and send the user a response and

1868
01:14:26,570 --> 01:14:33,229
I'm going to convert the string to the

1869
01:14:30,889 --> 01:14:35,389
type and I'm going to send this back to

1870
01:14:33,229 --> 01:14:37,130
them and convert is not a real function

1871
01:14:35,389 --> 01:14:38,900
so I need to implement convert so

1872
01:14:37,130 --> 01:14:40,280
converts going to take a string and a

1873
01:14:38,900 --> 01:14:41,869
type and it's going to convert that

1874
01:14:40,280 --> 01:14:43,429
string to the given type and this is

1875
01:14:41,869 --> 01:14:46,969
very easy to implement what I do is I

1876
01:14:43,429 --> 01:14:49,189
return a new buffer so new new buffer

1877
01:14:46,969 --> 01:14:51,979
will take this string turn it into a

1878
01:14:49,189 --> 01:14:54,800
buffer and then buffer hasn't has a two

1879
01:14:51,979 --> 01:14:57,050
string method that takes a type

1880
01:14:54,800 --> 01:14:58,610
okay so all I'm doing is I'm taking the

1881
01:14:57,050 --> 01:15:00,290
string that users given me I'm turning

1882
01:14:58,610 --> 01:15:01,820
it into a buffer like raw bytes and then

1883
01:15:00,290 --> 01:15:05,060
I'm converting it into the string form

1884
01:15:01,820 --> 01:15:07,430
that I want okay and so then that's what

1885
01:15:05,060 --> 01:15:09,650
I send back to them does this code make

1886
01:15:07,430 --> 01:15:15,620
sense everybody any obvious security

1887
01:15:09,650 --> 01:15:17,180
issues okay oh thank you yeah thank you

1888
01:15:15,620 --> 01:15:19,730
for that okay cool

1889
01:15:17,180 --> 01:15:23,240
okay so let's see if this worked so I'll

1890
01:15:19,730 --> 01:15:24,410
go to localhost 4000 slash I guess I

1891
01:15:23,240 --> 01:15:25,760
already have an example here so I don't

1892
01:15:24,410 --> 01:15:27,770
know if it one can see this but

1893
01:15:25,760 --> 01:15:29,780
basically I'm just going to slash API

1894
01:15:27,770 --> 01:15:32,990
slash convert and then my data query

1895
01:15:29,780 --> 01:15:35,150
value is just stirrers hello and the

1896
01:15:32,990 --> 01:15:37,550
type is hex so let's see this gives me

1897
01:15:35,150 --> 01:15:38,570
back a hex hex value of hello I don't

1898
01:15:37,550 --> 01:15:41,260
know if that's correct it looks correct

1899
01:15:38,570 --> 01:15:44,450
to me let's just go with it let's try

1900
01:15:41,260 --> 01:15:47,150
base64 that looks right to me let's try

1901
01:15:44,450 --> 01:15:49,580
changing this to a longer string okay it

1902
01:15:47,150 --> 01:15:51,530
looks like it's working what happens if

1903
01:15:49,580 --> 01:15:53,270
I don't give it valid JSON so let's say

1904
01:15:51,530 --> 01:15:55,100
I add like an extra some extra braces

1905
01:15:53,270 --> 01:15:57,080
here so it's not valid JSON cool it

1906
01:15:55,100 --> 01:15:59,630
handled the error the server didn't

1907
01:15:57,080 --> 01:16:01,010
crash right the server the server just

1908
01:15:59,630 --> 01:16:02,420
printed a warning but it didn't crash

1909
01:16:01,010 --> 01:16:05,840
okay whatever

1910
01:16:02,420 --> 01:16:09,590
so this looks good okay so what is the

1911
01:16:05,840 --> 01:16:13,970
problem what if I told you that changing

1912
01:16:09,590 --> 01:16:17,530
this parameter here from a string to a

1913
01:16:13,970 --> 01:16:21,830
number would be disastrous

1914
01:16:17,530 --> 01:16:23,510
like axe absolutely catastrophic okay I

1915
01:16:21,830 --> 01:16:25,310
will change this to the number 100 and

1916
01:16:23,510 --> 01:16:26,810
it's not in quotes you'll notice the

1917
01:16:25,310 --> 01:16:29,690
hundred is not in quotes it's actually a

1918
01:16:26,810 --> 01:16:34,610
number when I do that guess I'm getting

1919
01:16:29,690 --> 01:16:37,220
back this is raw server memory so I like

1920
01:16:34,610 --> 01:16:39,830
any what this is doing is if you're

1921
01:16:37,220 --> 01:16:42,110
familiar with malloc in C this is

1922
01:16:39,830 --> 01:16:43,820
calling malloc and it's not zeroing out

1923
01:16:42,110 --> 01:16:45,860
the memory so what this means is it's

1924
01:16:43,820 --> 01:16:47,840
giving me memory that was potentially

1925
01:16:45,860 --> 01:16:50,150
used for other things by this process

1926
01:16:47,840 --> 01:16:52,160
earlier in time and so this could could

1927
01:16:50,150 --> 01:16:54,350
potentially include sensitive user data

1928
01:16:52,160 --> 01:16:55,670
like you know the users password or

1929
01:16:54,350 --> 01:16:58,430
anything that was ever in memory in the

1930
01:16:55,670 --> 01:17:00,950
process at any point in the past so it's

1931
01:16:58,430 --> 01:17:03,440
pretty wild and if I if I actually let's

1932
01:17:00,950 --> 01:17:05,330
see let me um me refresh this a few

1933
01:17:03,440 --> 01:17:08,370
times actually let me let me change this

1934
01:17:05,330 --> 01:17:10,860
to utf-8 so utf-8 is is basically

1935
01:17:08,370 --> 01:17:14,880
the normal human readable like Unicode

1936
01:17:10,860 --> 01:17:15,750
text and so if I do that most of the the

1937
01:17:14,880 --> 01:17:17,760
bytes you're going to look at are not

1938
01:17:15,750 --> 01:17:19,290
valid like they're just garbage memory

1939
01:17:17,760 --> 01:17:21,120
but occasionally you'll get a string of

1940
01:17:19,290 --> 01:17:23,070
like user data or some string that looks

1941
01:17:21,120 --> 01:17:24,600
like it you know this was this wasn't a

1942
01:17:23,070 --> 01:17:26,400
member in memory of the process at some

1943
01:17:24,600 --> 01:17:29,640
point in time so if i refresh this few

1944
01:17:26,400 --> 01:17:34,410
times let's see so far nothing that

1945
01:17:29,640 --> 01:17:37,890
interesting whoa was it increase the

1946
01:17:34,410 --> 01:17:40,740
size sure yeah oh yeah let's make it

1947
01:17:37,890 --> 01:17:43,410
bigger yeah sure okay so this is looks I

1948
01:17:40,740 --> 01:17:45,840
mean okay this is interesting there's an

1949
01:17:43,410 --> 01:17:48,120
Arabic characters but there's there's

1950
01:17:45,840 --> 01:17:50,160
also like code and some something that

1951
01:17:48,120 --> 01:17:52,110
was in memory at one point in time yeah

1952
01:17:50,160 --> 01:17:54,300
yeah so if I kept doing that oh whoa

1953
01:17:52,110 --> 01:17:57,150
what is this this is this is a code from

1954
01:17:54,300 --> 01:17:58,980
express it looks like yeah okay so see

1955
01:17:57,150 --> 01:18:00,450
basically there was some memory of some

1956
01:17:58,980 --> 01:18:02,640
point in time that contained code and

1957
01:18:00,450 --> 01:18:08,010
then it got freed and then we mount it

1958
01:18:02,640 --> 01:18:10,560
and it wasn't zeroed out so this is this

1959
01:18:08,010 --> 01:18:13,680
is a bad API design basically whoo this

1960
01:18:10,560 --> 01:18:15,270
code looked totally benign right and it

1961
01:18:13,680 --> 01:18:17,100
turns out we were running a server which

1962
01:18:15,270 --> 01:18:18,720
completely just will just print out any

1963
01:18:17,100 --> 01:18:20,040
any user data that was ever in memory at

1964
01:18:18,720 --> 01:18:21,630
any point in time this is by the way

1965
01:18:20,040 --> 01:18:23,760
very similar to heartbleed never heard

1966
01:18:21,630 --> 01:18:25,380
about the heartbleed attack it was an

1967
01:18:23,760 --> 01:18:26,430
attack where you could send a request to

1968
01:18:25,380 --> 01:18:28,140
a server and it would just print out

1969
01:18:26,430 --> 01:18:29,790
random memory and eventually if you did

1970
01:18:28,140 --> 01:18:32,480
it enough times you would get the secret

1971
01:18:29,790 --> 01:18:34,380
key that is used for the TLS handshake

1972
01:18:32,480 --> 01:18:35,910
so you'd literally have the server's

1973
01:18:34,380 --> 01:18:38,880
secret key and you can men in the middle

1974
01:18:35,910 --> 01:18:40,920
all the users of that service so anyway

1975
01:18:38,880 --> 01:18:44,250
we don't have time to actually go into

1976
01:18:40,920 --> 01:18:44,970
exactly how this works but we'll talk

1977
01:18:44,250 --> 01:18:49,220
about it next time

1978
01:18:44,970 --> 01:18:49,220
and I'll see you all on Thursday thanks


