[00:01.800 --> 00:04.500] Alright, so do I have to repeat all that shit again? [00:05.200 --> 00:05.660] Alright. [00:06.590 --> 00:08.380] But is this part going to be on the DVD? [00:09.140 --> 00:10.360] Oh, that's great. [00:10.660 --> 00:11.940] What a phenomenal start. [00:16.120 --> 00:18.780] This gentleman has wanted to attend the HOPE conference for many years. [00:19.030 --> 00:21.220] He and Emmanuel have tried to work it out. [00:21.340 --> 00:22.720] He's very excited to be here. [00:22.880 --> 00:24.980] He's well respected in the computer security world. [00:25.680 --> 00:26.620] Dan Kaminsky. [00:36.940 --> 00:39.040] Holy crap, I finally made a HOPE. [00:39.440 --> 00:40.700] Took me long enough. [00:41.720 --> 00:43.780] So, hi, I'm Dan. [00:44.760 --> 00:46.380] I got a company, whatever. [00:49.140 --> 00:52.920] I want to start this talk by telling a story. [00:53.760 --> 01:01.160] Who here is familiar with the TLS renegotiation bug found by Marsh Ray last year? [01:02.580 --> 01:07.660] Was that not, like, the most beautiful bug that had come out in years? [01:08.120 --> 01:11.880] Like, this was a core crypto design flaw. [01:12.040 --> 01:14.260] It had been there since the beginning of SSL. [01:14.440 --> 01:21.160] It was one of those situations where two pieces of the protocol thought the same message meant two different things entirely. [01:21.620 --> 01:22.220] Beautiful. [01:24.040 --> 01:30.240] So, Marsh finds this bug, pulls together a whole bunch of people just like I did for DNS. [01:30.800 --> 01:34.700] And you know what the best part of, like, they did, like, months and months of secret work. [01:34.820 --> 01:36.480] You know what the best part of it was? [01:37.620 --> 01:40.480] I had nothing to do with it. [01:41.060 --> 01:42.640] No idea what was going on. [01:42.640 --> 01:45.460] I went to sleep every night blissfully unaware. [01:47.720 --> 01:49.640] So, this was a very big effort. [01:49.860 --> 01:53.260] They spent thousands of hours coming up with a very deep fix. [01:53.760 --> 01:56.500] The fix was almost perfect. [01:57.240 --> 01:57.720] Almost. [01:58.200 --> 02:05.420] The fix that ended up coming up with ended up not working on about, you know, 0.01, 0.03% of servers. [02:06.300 --> 02:07.740] But, you know, that's pretty good, right? [02:07.880 --> 02:10.880] You know, 99.7% compliance. [02:10.880 --> 02:13.260] I mean, that's totally good enough for deployment, right? [02:14.660 --> 02:15.220] Yeah. [02:15.560 --> 02:18.340] So, it's off by default everywhere in the known universe. [02:20.980 --> 02:21.540] Crap. [02:22.620 --> 02:23.000] No. [02:23.180 --> 02:25.600] So, this is interesting to me. [02:26.660 --> 02:28.960] A huge amount of effort was spent. [02:29.160 --> 02:30.900] A huge amount of code was written. [02:31.060 --> 02:33.240] A lot of political capital was exerted. [02:33.420 --> 02:35.920] No benefit to my mom. [02:37.020 --> 02:38.060] That's not cool. [02:39.380 --> 02:41.520] I got some bad news, and I got some good news. [02:41.760 --> 02:47.140] The bad news is, as hackers, we sometimes give really bad advice. [02:47.780 --> 02:50.800] Sometimes, we'll tell people, this is what you're going to do, and it'll be secure. [02:50.900 --> 02:52.860] And that's all that matters in the world. [02:53.380 --> 03:01.120] We, in more technical terms, only consider our own engineering requirements, which is that it can't get compromised. [03:02.000 --> 03:04.480] We assume that the environment is static. [03:04.700 --> 03:07.760] We assume that the tools are static, that things are going to be as they are. [03:08.080 --> 03:13.520] And, you know, the only thing we care about when we give our advice is, well, at least it's safe. [03:13.520 --> 03:18.000] And in the case of the TLS bug, well, at least I can turn it on for myself. [03:19.880 --> 03:21.240] So that's the bad news. [03:22.080 --> 03:34.740] The good news is, if things are ever actually to get better, if we're ever actually to see people having more secure systems, I'm going to tell you something. [03:34.740 --> 03:36.620] It ain't happening without hackers. [03:37.500 --> 03:42.060] People who don't know how to break into things really don't know how to fix them. [03:43.040 --> 03:50.260] At the end of the day, the analogy I've been using is, it's kind of like turning off your cell phone when you get onto the airplane. [03:50.600 --> 03:54.080] Whatever it has to do with, it's got nothing to do with safety. [03:54.840 --> 03:56.060] I got a secret. [03:56.320 --> 03:58.640] No one turns off their phones. [04:01.420 --> 04:11.620] So, let's start by talking about something that is really, really broken, which I hope, through some work, eventually, we can finally see get fixed. [04:13.620 --> 04:19.540] What we have here are two SSH sessions to two completely different servers. [04:19.780 --> 04:21.900] I've logged into two boxes. [04:22.640 --> 04:22.980] Okay. [04:23.920 --> 04:30.060] When I log into two SSH servers, do I need to worry about one of those servers hacking the other? [04:30.480 --> 04:31.080] No. [04:31.820 --> 04:38.820] When I log into two different websites, do I need to worry about one of those websites logging into the other? [04:39.460 --> 04:40.060] Yes. [04:40.500 --> 04:41.560] Why is this? [04:41.680 --> 04:49.040] Because session management on the web is totally broken, and session management in SSH works pretty well. [04:50.560 --> 04:54.660] The web was never designed to host authenticated resources. [04:55.340 --> 04:57.580] Authentication was basically bolted on. [04:57.860 --> 05:03.400] I mean, if you go to the beginning, once upon a time, the web was just like flat files in a directory. [05:03.700 --> 05:08.520] And then people started saying, hey, wait a second, we can make money if we be a little dynamic here. [05:08.880 --> 05:10.760] And that's when it all started going downhill. [05:15.210 --> 05:20.650] Now, the real-world normal mechanism by which credentials tend to be managed are cookies. [05:21.210 --> 05:27.450] The idea is that you have some form, you type in a password, because password is all we can finally make work after all these years. [05:28.590 --> 05:32.610] And you don't want to have to type in a password for every single web page you go to. [05:32.610 --> 05:37.570] So what we end up seeing is the first time you enter a password, you get a cookie back. [05:37.770 --> 05:42.990] A tiny little opaque blob that you now attach to every single request to a site. [05:43.190 --> 05:46.830] And now you don't have to keep putting in your password over and over and over again. [05:47.330 --> 05:48.730] That seems pretty reasonable. [05:49.270 --> 05:54.770] The thing is, cookies are attached to every single request to a site. [05:54.930 --> 05:58.110] Even if that request came from some foreign domain. [05:58.110 --> 06:03.610] So you're logged into your bank, and you're also browsing some random bad website. [06:03.830 --> 06:09.890] That random bad website can mix his URL request with your credentials. [06:10.530 --> 06:18.390] At the end of the day, this is why cross-site scripting and cross-site request forgery is a big deal. [06:18.690 --> 06:25.410] It's because the actual credentials that we use to log into websites are really, really leaky. [06:26.870 --> 06:38.430] Now, what we tend to say as hackers, as pen-testers is, well, when you log into a website, you should have a little extra blob attached to every single URL. [06:38.870 --> 06:46.510] And you might see this, you know, little blob of noise, you know, called token equals and some noise, wherever you're browsing the authenticated portions of a site. [06:48.290 --> 06:49.130] This works. [06:49.770 --> 06:50.630] So that's right. [06:50.710 --> 06:51.210] That's cool. [06:51.310 --> 06:51.610] It works. [06:51.710 --> 06:52.230] We got a solution. [06:52.390 --> 06:52.590] We're done. [06:53.850 --> 06:56.250] Amazingly enough, devs kind of hate this. [06:56.390 --> 06:58.210] Because cookies are automatic. [06:58.550 --> 07:02.010] You flip a switch, they work, the browser takes care of it, you're done. [07:02.490 --> 07:08.350] With this stuff, you have to touch every single URL in a web application. [07:08.790 --> 07:09.830] So you know what happens? [07:10.390 --> 07:11.430] People don't do it. [07:11.610 --> 07:14.710] And so we go ahead, we advise people, oh yeah, go through this token on. [07:14.710 --> 07:23.350] And then they try, and they realize it's going to be more work to add this little token than it was for them to write the web application in the first place. [07:23.490 --> 07:25.150] And so they go tell you to pound sand. [07:25.330 --> 07:27.610] And then you come back six months later, and you have the same finding. [07:27.730 --> 07:30.250] And you keep doing this until the pen-test budget's exhausted. [07:33.170 --> 07:36.570] So, couldn't the tools be a little better? [07:37.770 --> 07:46.050] Every time I look at the web scene, I see people arguing about whether SVG files should be able to animate. [07:46.590 --> 07:47.510] That's nice. [07:47.670 --> 07:48.250] That's cool. [07:48.490 --> 07:52.770] Could we maybe have the ability to log into a website securely? [07:53.650 --> 07:55.530] Maybe that's a little more important? [07:58.320 --> 07:59.820] So I tried to build this. [08:00.320 --> 08:14.840] I went ahead, and I built four different systems that tried to go ahead and make it so you knew when you were browsing a website that you were any request actually came from the site at play. [08:15.100 --> 08:23.920] In other words, I want to be able to differentiate when the site I'm logged into sends me somewhere versus when some other site does this. [08:24.120 --> 08:26.280] This shouldn't be a complicated thing. [08:26.280 --> 08:27.520] It's really hard. [08:27.780 --> 08:29.860] So I came up with four different mechanisms. [08:30.180 --> 08:31.880] We don't need to go into the details. [08:32.100 --> 08:35.360] I just want to say they all got owned thoroughly. [08:36.000 --> 08:40.300] Thank you, Seastone, Kusa55, Amit Klein, Dave Ross, and SirDarkat. [08:41.220 --> 08:43.040] This is awesome. [08:44.180 --> 08:46.140] We have a bit of a problem in our scene. [08:46.500 --> 08:53.020] And one of those problems is we're really slow to get around to actually breaking stuff. [08:53.020 --> 08:57.600] I don't know if you've noticed, we don't break things when they're originally being developed. [08:57.800 --> 08:59.620] We don't break them when they're released. [08:59.680 --> 09:03.760] We don't even break them when early adopters are using them. [09:03.760 --> 09:09.640] What happens is something gets to a certain popularity level, and then all of a sudden we're like, Oh, wow! [09:10.220 --> 09:11.900] Lots of people are using this thing. [09:12.240 --> 09:13.720] Let's find out if it's crap. [09:17.340 --> 09:18.240] A little late. [09:20.860 --> 09:22.820] We need to close this feedback loop. [09:22.860 --> 09:35.240] We need to get to the point where, when major new technologies are looking like they're going to get adopted, we have a reason to believe that they have been thoroughly and publicly and brutally audited. [09:37.140 --> 09:38.900] So, here's the deal. [09:39.400 --> 09:45.460] Whatever is going on with everyone else's defenses, I want mine to get destroyed. [09:46.280 --> 09:53.640] No question, no delay, because life is too short to back broken code. [09:54.100 --> 09:59.880] What could possibly be worse than spending years of your life on a defense and then one day finding out, Oh, yeah! [10:00.160 --> 10:02.040] That doesn't work at all. [10:03.060 --> 10:06.700] Session management is going to require some pretty deep changes to the browser. [10:06.940 --> 10:12.040] And if you're interested in it, come up, walk up to me, and we can talk about some of the details. [10:12.740 --> 10:18.840] There is something else that might not require nearly this sort of deep changes. [10:21.160 --> 10:25.860] There's a really interesting guy I've known for about 10 years, Jeremiah Grossman. [10:26.280 --> 10:28.540] He runs a company called White Hat Security. [10:28.540 --> 10:32.500] White Hat does tremendous amounts of website auditing. [10:33.360 --> 10:39.880] And he has something that a lot of us really should be looking at more, which is data. [10:40.460 --> 10:42.810] We tend to run a lot on anecdotes. [10:43.600 --> 10:44.540] You know, oh, I heard. [10:45.140 --> 10:50.540] There is power in actual concrete information about how things fail. [10:51.100 --> 10:54.920] One of the things that Jeremiah found, and I'm just going to quote him in entirety. [10:54.920 --> 11:03.360] The bottom line is there just is not a measurable difference in the security postures from language to language or framework to framework. [11:03.760 --> 11:09.660] Specifically, Microsoft ASP Classic, .NET, Java, ColdFusion, PHP, and Perl. [11:10.140 --> 11:19.320] Sure, in theory, one might be significantly more secure than the others, but when deployed on the web, it's just not the case. [11:19.860 --> 11:29.460] I'm not going to ask you to raise your hands, but I bet a lot of you in this room absolutely assumed that mattered what language you use and what framework you use. [11:29.460 --> 11:38.020] But when you have a guy who's actually going out there breaking websites by the thousands, eh, 10% difference here, 20% difference there. [11:38.360 --> 11:40.640] It's not a big difference what's going on. [11:41.160 --> 11:46.520] Now, I don't think even Jeremiah realized how significant this finding is. [11:46.640 --> 11:55.800] Because, you know, we've got some languages in here that are type safe, and we've got languages in here that are most assuredly not type safe. [11:55.800 --> 11:59.360] We're spending a lot of money on this safety. [12:00.040 --> 12:01.800] Where's the safety? [12:02.500 --> 12:08.380] This is a huge and massive and order of magnitude expenditure we're making. [12:08.580 --> 12:12.500] Why aren't we getting the safety we're paying for? [12:14.100 --> 12:21.520] Well, one thing to be clear about, we're not really actually using type safe languages, even when we think we are. [12:22.080 --> 12:28.620] The reality of web development is, when you sneeze, you're in a new programming language. [12:28.860 --> 12:32.900] You got HTML, you got JavaScript, you got CSS, a little bit of XML, let's bust in some SQL. [12:33.120 --> 12:34.000] How about some PHP? [12:34.260 --> 12:35.440] Okay, now we'll do some C-sharp. [12:35.760 --> 12:38.780] Every time you move, it's a new language. [12:39.200 --> 12:42.900] All of these languages need to communicate with one another. [12:43.060 --> 12:45.020] And they all have their own type systems. [12:45.120 --> 12:46.520] They all have their own internal things. [12:46.520 --> 12:56.860] But when you need to have cross-language communication, from PHP to SQL, from C-sharp to HTML, how does it end up working? [12:57.100 --> 12:59.240] It works through strings. [12:59.700 --> 13:01.640] Just raw text. [13:01.920 --> 13:03.800] There's no type safety involved. [13:03.960 --> 13:06.100] There's no context involved. [13:06.380 --> 13:08.300] It's just, here's some programming. [13:15.380 --> 13:18.540] So, this time last year, I would have told you type safety was useless. [13:18.960 --> 13:19.940] Turns out I was wrong. [13:21.320 --> 13:22.460] Happens quite a bit, actually. [13:24.080 --> 13:26.620] Never, by the way, be afraid of being wrong. [13:27.000 --> 13:30.360] Being wrong just means the world is more interesting than you thought it was. [13:32.900 --> 13:35.100] So, all injections are actually type bugs. [13:35.100 --> 13:48.760] If I have a straight-up SQL injection, just like count star from foo where x equals x or 1 equals 1, and the injected string is x single quote or single quote 1 single quote equals single quote 1. [13:49.920 --> 13:58.680] When that goes out, the C-sharp and PHP or Java or Ruby sender thinks this red area is just a string. [13:58.840 --> 14:02.080] That's just another thing, you know, little bobby tables. [14:06.240 --> 14:08.760] But the receiver sees something else entirely. [14:09.120 --> 14:14.300] The receiver is like, oh, there's a string and a concatenator and another string and a comparator and another string. [14:14.640 --> 14:19.160] So, what we have here is a failure to communicate. [14:19.480 --> 14:26.920] We have different grammatical structures being seen from the same string. [14:26.920 --> 14:33.220] So, the challenge, when I talk about type safety, what I'm saying is there's a grammar. [14:33.520 --> 14:39.380] There's a overall meta-understanding beyond just here's a sequence of bits. [14:39.560 --> 14:46.280] And what we want is we want that meta-understanding to be synchronized between a sender and a receiver. [14:47.360 --> 14:49.480] That's ultimately our challenge. [14:49.480 --> 14:52.400] Now, people think this is a solved problem. [14:52.600 --> 14:54.560] They say, well, we've got escapes. [14:54.980 --> 14:56.700] We've got parameterized queries. [14:57.540 --> 14:59.460] So, what's the problem here? [14:59.880 --> 15:04.780] Clearly, all we have are developers that are lazy and stupid. [15:05.900 --> 15:11.620] And this is great for us because it, like, defines us as intelligent and industrious. [15:13.180 --> 15:14.660] Wonderful for our egos. [15:14.820 --> 15:17.940] Does nothing to protect my mom from insecure code. [15:21.340 --> 15:24.140] So, why is this not a solved problem? [15:27.320 --> 15:27.840] Escaping. [15:28.620 --> 15:29.240] All right. [15:29.320 --> 15:30.760] So, I'm looking at some PHP code. [15:30.860 --> 15:34.100] And I see, okay, I got a connection object. [15:34.100 --> 15:37.800] Queries, like, star from foo where x equals dollar sign foo. [15:39.200 --> 15:41.620] Is that safe or is that vulnerable? [15:41.840 --> 15:42.880] I don't know. [15:43.480 --> 15:55.900] I got to trace back through, like, ten functions to look to see in any of those ten functions between when the bytes came in on the wire and this query is happening, where magic bad characters escaped. [15:56.180 --> 15:57.340] Because they might have been. [15:57.540 --> 15:59.280] They might not have been. [15:59.400 --> 16:01.540] But I got to sit there and I got to look. [16:01.760 --> 16:03.360] And you know what's worse than that? [16:04.600 --> 16:10.380] I may find that there's an escaper that goes ahead and takes any of those bad characters and removes them. [16:10.560 --> 16:13.420] If there's a bad character, this query is going to be vulnerable. [16:14.540 --> 16:18.620] Someone, three months from now, can remove the escape. [16:18.920 --> 16:20.080] They can say, you know what? [16:20.180 --> 16:21.100] Something's going wrong. [16:21.100 --> 16:21.880] There's a bug. [16:22.020 --> 16:24.720] And what does every developer do whenever there's a bug? [16:25.000 --> 16:28.580] He turns off the security because it might be the security's fault. [16:29.220 --> 16:34.560] And then, you know what he does after he finds the actual bug that had nothing to do with security? [16:35.080 --> 16:37.420] He doesn't put the security back. [16:38.680 --> 16:40.420] And does this cause a problem? [16:40.640 --> 16:40.880] No. [16:41.440 --> 16:44.660] Code works just fine without that escape. [16:44.880 --> 16:46.060] It's there, you know. [16:46.320 --> 16:47.200] It's there if it's there. [16:47.300 --> 16:47.900] It's not if it's not. [16:48.020 --> 16:49.120] The code works anyway. [16:49.120 --> 16:51.900] This is what's called failing open. [16:52.120 --> 16:53.780] Or for short, failing. [16:59.080 --> 17:00.360] Here's another problem. [17:00.620 --> 17:02.960] Actually, this is the real problem with escaping. [17:03.280 --> 17:05.360] What does it mean to escape? [17:05.820 --> 17:08.300] Well, we're blocking evil characters. [17:08.940 --> 17:12.400] Once upon a time, we had ASCII. [17:12.560 --> 17:16.220] And we had, like, less than 256 characters. [17:16.420 --> 17:20.260] And that was the scope of things that could possibly go wrong. [17:20.260 --> 17:23.140] That was long in the distant past. [17:23.380 --> 17:25.300] Now we got Unicode. [17:25.460 --> 17:34.760] And with Unicode, we got millions of characters with at least a half dozen to a dozen possible representations for those characters. [17:34.760 --> 17:37.760] And by the way, they can mutate. [17:38.320 --> 17:40.900] Anyone here know what's called best fit matching? [17:41.760 --> 17:44.000] Best fit matching is totally obscure. [17:44.060 --> 17:44.680] It's great. [17:44.680 --> 17:50.140] You've got characters in other languages that really, really look like slashes. [17:50.700 --> 17:52.160] And so you know what happens? [17:52.540 --> 17:55.520] All this software says, well, it looks like a slash. [17:55.840 --> 17:57.780] I'm gonna treat it like a slash. [17:58.680 --> 17:59.680] This does really... [18:00.420 --> 18:02.060] Can I have your attention, please? [18:02.420 --> 18:02.900] Absolutely. [18:03.200 --> 18:03.700] What would you like? [18:03.800 --> 18:06.000] You're conducting a test of a fire safety equipment. [18:06.240 --> 18:07.180] Ha, ha, ha, ha! [18:07.960 --> 18:08.340] Please, [18:17.660 --> 18:17.780] please. [18:18.820 --> 18:19.300] Right. [18:26.110 --> 18:27.670] What could possibly go wrong? [18:31.250 --> 18:32.470] All right, seriously. [18:33.510 --> 18:34.860] Turn off your cell phones, please. [18:38.540 --> 18:39.470] No, uh... [18:40.100 --> 18:50.160] Yeah, so the reality of Unicode is if you think you can know in advance which characters are the dangerous ones, I'm sorry, you're just wrong. [18:50.400 --> 18:51.660] It's not like a bad thing. [18:51.750 --> 18:52.620] It's not like you were lazy. [18:52.620 --> 18:56.680] They've just overloaded what something means to be a character. [18:56.970 --> 18:58.290] We don't have characters anymore. [18:58.290 --> 18:59.270] We have code points. [18:59.360 --> 19:01.530] And they do super weird things. [19:02.890 --> 19:07.620] So, the deal with escaping is ultimately it works by accident. [19:07.940 --> 19:09.600] There's no established contract. [19:09.860 --> 19:16.360] You basically are saying, dear other side, here's what I think are gonna be the dangerous characters. [19:16.770 --> 19:18.360] Hopefully, I got them all. [19:18.360 --> 19:20.470] And, um... [19:20.470 --> 19:22.080] Here's what actually happens. [19:22.470 --> 19:30.640] We have in JavaScript today the escape function, the escape URI function, and the escape URI component function. [19:31.120 --> 19:39.340] To translate, that's the we screwed up function, we screwed up again function, and the I hope I got it right this time function. [19:43.910 --> 19:46.250] Escaping always looks like a good idea. [19:46.410 --> 19:47.250] It never actually is. [19:48.210 --> 19:50.270] Now, what about parameterized queries? [19:50.710 --> 19:59.070] In parameterized queries, we follow the old model that says that code and data should come in through completely different channels. [19:59.290 --> 20:05.250] And so, you have, like, your safe stuff, and you have your unsafe stuff, and never the two should meet. [20:05.670 --> 20:11.690] This, of course, is basic security theory and makes us feel so warm and fuzzy inside. [20:12.470 --> 20:14.370] You know who doesn't make feel happy? [20:14.490 --> 20:15.070] The dev. [20:15.310 --> 20:18.470] Because if you're the dev, you're saying, well, I have this one line of code. [20:18.650 --> 20:23.690] It's like star from foo where fname equals fname and lname equals lname and address equals address and city equals city. [20:23.930 --> 20:24.250] Done. [20:24.390 --> 20:25.250] Move on with my life. [20:25.310 --> 20:26.210] And that's one line. [20:26.370 --> 20:32.850] Or I could write one, two, three, four, five, six lines of code. [20:35.600 --> 20:36.320] Oh, yeah. [20:36.500 --> 20:39.000] I want him to escape those dollar signs. [20:39.180 --> 20:40.120] He does not. [20:41.820 --> 20:47.020] The reality is, is that no developer has ever written a parameterized query without a gun to his head. [20:47.180 --> 20:48.080] We should know. [20:48.240 --> 20:49.640] We hold the gun. [20:52.380 --> 20:54.160] Why do devs hate this? [20:54.620 --> 20:54.820] Look. [20:55.620 --> 20:56.300] Positional. [20:56.620 --> 20:59.340] Anyone here ever do win 32 coding? [21:00.680 --> 21:01.240] Okay. [21:01.600 --> 21:04.460] Positional argument delivery does not scale. [21:05.440 --> 21:08.060] I want you to look at an example from Mike Samuel. [21:08.060 --> 21:11.980] He's a brilliant engineer over at Google who's been doing some similar work. [21:12.480 --> 21:13.720] Very similar, in fact. [21:15.040 --> 21:16.340] And here's this example. [21:16.560 --> 21:19.820] I met a question mark in the question mark who had a question mark full of question mark. [21:19.900 --> 21:20.940] He said, hello, question mark. [21:20.980 --> 21:21.680] How are you today? [21:21.880 --> 21:23.040] It goes on like that. [21:23.140 --> 21:29.500] And then after all of this, you have profession and landmark and container and species of monkey and a proper name. [21:31.900 --> 21:37.400] This is actually as annoying to write as it is to audit. [21:37.700 --> 21:46.060] Let me trace out for you from a user interface perspective what this line of code or what this batch of code means. [21:46.660 --> 21:49.200] Your eye has to do that. [21:50.720 --> 21:54.840] And more importantly, this is a problem. [21:55.860 --> 21:58.840] Nobody ever thinks about user interfaces for developers. [21:58.840 --> 22:02.560] Nobody ever thinks about what is actually convenient for them. [22:02.720 --> 22:07.460] Because, hey, we're just going to tell people what to do and security is the only thing that matters. [22:07.900 --> 22:10.580] And then we turn around in six months and we don't have what we want. [22:10.620 --> 22:11.540] And we're very confused. [22:14.200 --> 22:20.440] Developers do not give a crap about this code data separation because that's not how they're thinking. [22:20.660 --> 22:23.240] It's not separated in their heads. [22:23.640 --> 22:29.600] What developers want to do is they want to say, select count star from foo where x equals foo. [22:29.780 --> 22:30.540] Just get foo. [22:30.740 --> 22:31.380] Get right there. [22:31.560 --> 22:32.300] Right in line. [22:32.560 --> 22:41.800] And if they don't have in line what's called interpolation syntax in the language, they will do horrifying things with what's called string concatenation. [22:42.620 --> 22:47.660] Select count star from foo where x equals backslash double quote, double quote plus. [22:47.660 --> 22:51.360] dollar sign underscore get foo plus, you know, double... [22:51.360 --> 22:52.180] They... [22:52.780 --> 22:55.240] I can't keep track of all this punctuation. [22:55.440 --> 22:56.560] Somehow they're able to. [22:57.240 --> 23:00.900] The reason they write code this way is because they're thinking in line. [23:01.140 --> 23:03.380] And they want to be writing in line. [23:03.700 --> 23:14.840] There is a theory in user interface design called Fitts' Law that says that your ability to work with a computer system is related to the size of what you're using and the distance you have to move. [23:15.000 --> 23:18.160] In line operations minimize both. [23:18.560 --> 23:21.520] And that is why that is how they want to work. [23:22.600 --> 23:24.060] So here's my question. [23:24.580 --> 23:31.600] Is it possible to let developers write in line code without exposing the resultant strings to injections? [23:31.980 --> 23:33.280] We know what they want to do. [23:33.440 --> 23:34.560] We know what we want. [23:34.560 --> 23:37.900] Is it possible for us both to get what we want? [23:38.140 --> 23:40.100] And the answer is yes. [23:40.260 --> 23:43.440] By making string interpolation smarter. [23:43.780 --> 23:48.540] String interpolation is where you're in the middle of writing some code and then you say, oh, wait. [23:48.720 --> 23:53.320] Now I want to put in the environment provided variable. [23:53.520 --> 23:54.360] And it's just in line. [23:54.440 --> 23:55.140] It's just magic. [23:56.780 --> 24:09.200] Normally, this is done by just taking the string that came from the bad guy and just smashing it into the string that came from the programmer and hoping for the best. [24:09.520 --> 24:09.900] Okay. [24:10.100 --> 24:10.940] That's not working. [24:11.400 --> 24:15.140] But what can work, there's still a boundary. [24:15.860 --> 24:22.680] The compiler still can see this is what came from the programmer and this is what came from the attacker. [24:23.220 --> 24:25.560] That boundary exists. [24:25.560 --> 24:26.820] It's not gone. [24:26.920 --> 24:31.640] It can be gone if you just smash the strings together, but it doesn't have to be. [24:32.880 --> 24:38.460] Step one is to retain the boundary as a critical piece of metadata. [24:38.920 --> 24:43.900] As the, in fact, important chunk that says, here's code, here's data. [24:44.140 --> 24:45.460] The line is still there. [24:46.040 --> 24:51.980] And then, now that we have this little piece of metadata, we can actually translate. [24:52.340 --> 24:55.600] We can take the string that was provided by the coder. [24:55.600 --> 25:13.640] We can take the string that was provided by the environment and we can do an intelligent, grammatically aware transformation such that what is actually run is ultimately what the compiler needed to see in order to emit safe code. [25:14.140 --> 25:18.940] This, again, does overlap with Mike Samuels' work called Secure String Interpolation. [25:18.940 --> 25:20.340] Go Google it. [25:20.460 --> 25:23.080] It's a wonderful piece of descriptive write-up. [25:23.440 --> 25:24.740] And we're working together. [25:26.460 --> 25:29.980] So, let's talk about what this actually looks like in the field. [25:30.320 --> 25:35.160] So, first of all, there is open source BSD code out there for Interpolique. [25:35.700 --> 25:36.860] It has a full demo. [25:37.380 --> 25:41.260] If you can break it, that's the greatest thing in the world for me. [25:41.260 --> 25:45.260] So, here we have a very simple form implementation. [25:45.700 --> 25:52.320] There's an author of foo and there's a description, you know, single quote or one equals one semicolon. [25:52.520 --> 25:53.700] Very, very basic. [25:53.700 --> 25:56.060] If there is a problem, this is going to inject it. [25:56.140 --> 25:57.260] This is little bobby tables. [25:57.540 --> 26:00.160] If we go ahead and post this, you know what? [26:00.240 --> 26:01.120] Nothing goes wrong. [26:01.360 --> 26:07.260] There's a data field, you know, foo quote or one equals one. [26:07.840 --> 26:09.240] No injections possible. [26:09.240 --> 26:10.640] Okay, that's kind of cool. [26:10.960 --> 26:12.140] What about the other direction? [26:12.720 --> 26:14.680] We want to have posts on a forum. [26:14.840 --> 26:16.060] We want to have a little bit of HTML. [26:16.460 --> 26:20.640] Let's go ahead and throw an image, some random IMGUR link. [26:20.960 --> 26:24.100] And, oh, you know, how about some cross-site scripting with that? [26:24.820 --> 26:28.080] Well, we'll see the image actually does get through. [26:29.060 --> 26:30.820] But the script does not. [26:31.160 --> 26:33.620] That alert one is now just stripped down to text. [26:34.840 --> 26:38.100] So, there are many ways of implementing this. [26:38.100 --> 26:39.040] They're kind of tricky. [26:39.320 --> 26:40.280] You've got to do escaping. [26:40.600 --> 26:42.200] You've got to be aware of stuff. [26:42.820 --> 26:44.620] How about what if you didn't? [26:45.200 --> 26:51.620] What if you as a developer could write the dumbest code in the world and it was still safe? [26:51.940 --> 26:59.120] What if you could just say, insert into post values, hey, I want the post that's the author and I want the post that's the content. [26:59.120 --> 27:00.880] I don't want to worry about escaping. [27:01.060 --> 27:02.280] I don't want to worry about this stuff. [27:02.540 --> 27:06.640] And sending stuff back to the browser for each row in the database. [27:06.860 --> 27:08.520] Just go ahead and emit data. [27:08.980 --> 27:09.960] Give me the author. [27:10.240 --> 27:11.040] Give me the content. [27:11.320 --> 27:13.500] Throw a BR at the end to give me a new line. [27:13.820 --> 27:14.180] Done. [27:15.040 --> 27:15.400] Okay. [27:15.640 --> 27:16.360] Let me tell you. [27:16.460 --> 27:18.120] This is what the dev wants to write. [27:18.240 --> 27:24.420] He does not want to think about all the things we tell them to do because they're complicated and, let's be honest, kind of fragile. [27:26.800 --> 27:28.360] So what's going on? [27:28.500 --> 27:29.980] Language interpolators are blind. [27:30.180 --> 27:31.840] They just push strings into strings. [27:32.160 --> 27:34.660] We are being a little smarter. [27:35.940 --> 27:40.900] The first form of translation that we can do, and this is on the SQL injection side. [27:41.200 --> 27:58.340] There is no reason, once we have the dynamic string with the barriers maintained, retained, that we can't expand from the string the programmer wants to write, select star from table where fname equals fname and country equals country and x equals x. [27:58.620 --> 28:08.060] There is no reason we can't expand that to statement equals a prepared statement, and then dynamically, why don't we bind fname country and x to bind param? [28:09.120 --> 28:11.120] Works like a charm. [28:11.620 --> 28:13.400] So that's the first thing we can do. [28:13.720 --> 28:18.980] The second thing we can do, okay, we could automatically inject the escapes. [28:18.980 --> 28:19.980] I'm sorry. [28:20.060 --> 28:21.380] It's just not going to work. [28:21.540 --> 28:25.660] In a Unicode world, you just don't know what characters are valid. [28:25.940 --> 28:29.220] It's not just JavaScript, by the way, that's had this problem with escapes. [28:29.560 --> 28:30.680] What does MySQL have? [28:30.900 --> 28:31.980] Two escape strings? [28:32.200 --> 28:32.340] Three? [28:32.720 --> 28:33.200] Maybe four? [28:34.060 --> 28:34.320] Yeah. [28:35.160 --> 28:36.060] Forget escapes. [28:38.440 --> 28:41.900] Then there's the glorious hack that is base 64. [28:45.090 --> 28:48.870] You know, you can actually go ahead... [28:48.870 --> 28:50.950] Let's just go into the explanation here. [28:52.390 --> 28:53.850] We go ahead... [28:53.850 --> 29:07.170] Actually, so we go ahead and we basically select star from table where fname equals Base64 decode function, big blob of Base64, and country equals b64d, another big blob of Base64. [29:07.170 --> 29:09.390] Why would you do this? [29:09.790 --> 29:14.230] Well, we're typesafe going into b64d. [29:14.630 --> 29:18.490] You know what a big batch of Base64 is never going to be confused for? [29:18.710 --> 29:19.570] Let me tell you. [29:19.770 --> 29:20.850] That ain't SQL. [29:21.090 --> 29:22.050] That ain't JavaScript. [29:22.430 --> 29:23.910] That ain't HTML. [29:24.270 --> 29:25.490] It's crap. [29:26.450 --> 29:27.170] Yes! [29:28.630 --> 29:33.690] Not only are we typesafe going in, we're typesafe coming out. [29:33.690 --> 29:37.190] Because base64d as a function is cast. [29:37.390 --> 29:39.850] It is returning a string. [29:40.230 --> 29:42.090] It's not returning a subquery. [29:42.270 --> 29:43.570] It's not returning a comparator. [29:43.750 --> 29:47.430] There's a billion grammatical elements that could be returned. [29:47.730 --> 29:51.230] This is the thing that is being returned. [29:51.710 --> 29:55.350] So, this is actually kind of awesome. [29:55.730 --> 29:59.130] This is type safety across language boundaries. [30:00.370 --> 30:03.890] Now, there are two models in which this can actually be implemented. [30:04.470 --> 30:11.630] You can basically have your web application and everything is normal. [30:11.810 --> 30:19.410] And then right at the, say, PHP to MySQL barrier, right there, you say, wait, wait. [30:19.630 --> 30:22.190] I'm passing this through like some SQL parser. [30:22.270 --> 30:24.090] Let me go ahead and wrap things up. [30:24.590 --> 30:25.910] And this works great. [30:25.950 --> 30:27.150] This is what's called late binding. [30:27.850 --> 30:30.410] The other approach is early binding. [30:31.130 --> 30:36.210] Where you Base64 the variable as soon as it comes in from the HTTP request. [30:39.170 --> 30:43.910] And as it passes through all of those functions, it remains Base64 encoded. [30:44.090 --> 30:45.450] So, it's a big pile of crap. [30:45.710 --> 30:49.890] If any of those intermediate functions actually need to work on it, they need to decode. [30:50.150 --> 30:51.290] They need to look inside. [30:51.510 --> 30:52.450] They need to change what they do. [30:52.570 --> 30:53.650] And then they need to re-encode. [30:54.710 --> 30:57.770] Now, here's what makes these approaches interesting. [30:58.870 --> 31:02.830] In the first one, and by the way, I didn't mention this, there's a new syntax. [31:03.050 --> 31:06.530] Instead of dollar sign foo, you have caret, caret foo. [31:06.670 --> 31:08.670] And the reason why it's dollar sign... [31:08.670 --> 31:17.090] The reason why it's caret, caret foo, instead of dollar sign exclamation point foo, is it's just too easy to confuse dollar sign foo and dollar sign exclamation point foo. [31:17.090 --> 31:19.430] So, we're doing a whole new character here. [31:21.230 --> 31:23.170] The reason this is interesting... [31:23.170 --> 31:25.350] Let's look at this second option. [31:25.590 --> 31:28.470] It's like star from foo where x equals b64 d foo. [31:29.530 --> 31:33.230] So, you might look at this and say, hey, you're using old interpolation syntax. [31:33.890 --> 31:44.610] That foo could have some SQL injections in there if it ever received anything that was not itself already encoded, already crapified, if you will. [31:44.910 --> 31:45.910] This is true. [31:46.230 --> 31:47.410] But here's what's awesome. [31:47.710 --> 31:53.150] When you remove the escape function, nothing goes wrong. [31:53.790 --> 32:05.030] If this SQL here ever receives data legitimately that is not Base64 encoded, the world comes to an end for the web app. [32:05.390 --> 32:08.090] It fails closed. [32:08.750 --> 32:10.050] This is awesome. [32:11.250 --> 32:21.630] So, as a kind of a concept here, you know what's better than having a static analyzer that will tell you exactly what's happening to a variable as it traverses through your application? [32:22.870 --> 32:24.750] Not needing one. [32:25.670 --> 32:28.510] If it works, it's working securely. [32:28.790 --> 32:33.990] If it's not working, then you still have work to do because it's not working. [32:35.130 --> 32:41.230] We have to make security and reliability linked as tightly as possible. [32:42.810 --> 32:46.270] It also turns out that this works in the other direction. [32:46.690 --> 32:47.250] Hang on a second. [32:47.370 --> 32:48.430] I'm just grabbing some water here. [32:53.900 --> 32:54.520] All right. [33:00.810 --> 33:08.350] So, you may have noticed getting developers to deal with cross-site scripting in a reasonable way is a whole bunch of work. [33:08.690 --> 33:15.690] And the reason why is because they just want to take their variables in their application and, you know, vomit them into the browser DOM. [33:15.890 --> 33:17.210] You know, what's the problem with that? [33:18.810 --> 33:24.770] One thing we can do is we can have the developer still just goes ahead and does caret caret internal variable. [33:25.050 --> 33:25.690] It just works. [33:26.350 --> 33:29.910] But what is admitted into the browser is something completely different. [33:30.250 --> 33:36.870] We go ahead and we say, oh, I have some text that needs to come from potentially attacker-controlled material. [33:37.170 --> 33:38.250] I'm going to create a span. [33:38.310 --> 33:39.550] It's going to have an ID. [33:39.610 --> 33:42.890] And it's going to have some Base64 encoded text. [33:42.930 --> 33:49.190] And then the first thing that's going to happen is I'm going to call a decode function on that ID. [33:49.490 --> 33:55.210] And it's going to turn this Base64 text into whatever is supposed to be in that span. [33:58.210 --> 34:00.090] This might seem a little obtuse. [34:00.410 --> 34:03.710] What it is, is really frickin' fast. [34:04.070 --> 34:06.590] There are people in security who think performance doesn't matter. [34:06.750 --> 34:07.410] They're wrong. [34:07.550 --> 34:12.750] If what you deploy is really, really slow, people will just not deploy what you have. [34:13.150 --> 34:18.510] So, what is interesting about this particular construction is, first, it streams. [34:18.510 --> 34:33.310] If you are streaming through a web page and just going from top to bottom and rendering as you can, whenever you see the span, immediately after the span is parsed, the thing shows up to decode the span into whatever text it's supposed to be. [34:34.050 --> 34:35.990] It took actually some work to do this. [34:37.090 --> 34:39.870] CP of DC949 actually came up with a fix. [34:39.970 --> 34:41.090] And it's kind of beautiful. [34:42.370 --> 34:43.530] So, what do you do? [34:43.730 --> 34:47.990] You go ahead and you are sitting here and you've got ZM9V. [34:47.990 --> 34:52.050] And that is supposed to be whatever is supposed to be inside this span. [34:52.590 --> 34:53.050] Okay. [34:53.070 --> 34:54.370] So, what do you do? [34:54.650 --> 34:56.150] I'll tell you what you don't do. [34:56.310 --> 34:59.470] You don't trust the browser's HTML parser because that thing... [34:59.470 --> 35:00.830] I don't know what the hell it's doing. [35:01.030 --> 35:06.130] I can't reason or analyze about the behavior of the browser's HTML parser. [35:06.290 --> 35:09.290] It is designed to parse code that is crap. [35:09.670 --> 35:10.350] That's okay. [35:10.570 --> 35:12.390] That's why HTML won. [35:12.390 --> 35:24.970] People don't realize this, but HTML was the first programming language, and it is a programming language, that you could have no idea what you were doing, but you'd still get something. [35:27.590 --> 35:29.050] This is wonderful. [35:29.610 --> 35:33.310] Nothing else works like this, but HTML did and that's why it won. [35:34.550 --> 35:44.270] So, that's great and wonderful for, you know, whoever's learning HTML, but if you want to reason about the security aspects of a system, eh, good luck. [35:44.650 --> 35:48.110] So, we're going to bypass that whole HTML parser thing. [35:48.210 --> 35:52.110] We're just going to talk to the browser document object model directly. [35:52.410 --> 35:54.370] The browser basically builds a tree. [35:54.370 --> 35:57.190] It says, oh, I've got some text over here. [35:57.190 --> 35:58.810] I've got some images over here. [35:58.870 --> 36:03.070] And when you write HTML, the HTML is translated into this tree. [36:03.230 --> 36:04.370] And you can do that. [36:04.590 --> 36:09.710] But another thing you can do is you can say, hey, tree, I got some text for you. [36:09.950 --> 36:11.190] It's text. [36:11.190 --> 36:12.390] It's not an image. [36:12.430 --> 36:13.570] It's not a script. [36:13.930 --> 36:15.130] It's text. [36:16.310 --> 36:19.810] See how that plays into the whole, we've got to keep the grammar straight? [36:19.810 --> 36:25.610] If you want a browser to create a text node, tell it to create a text node. [36:25.770 --> 36:26.810] And that works fine. [36:27.210 --> 36:35.130] So, one thing you can do is you just say, look, every element in the browser has what's called the text content field, at least every span does. [36:35.450 --> 36:41.510] We go ahead, we take that Base64 blob, we push it straight into the text content of the span. [36:42.050 --> 36:42.590] Boom. [36:42.830 --> 36:45.510] Cross-site scripting can't happen. [36:45.510 --> 36:49.370] We've skipped the entire code base that's trying to run script. [36:51.370 --> 36:59.110] However, it may very well be the case that you want to do a little more than just push some text in. [36:59.310 --> 37:02.570] Maybe this is a forum and you want to be able to push images. [37:02.990 --> 37:04.170] Can you do that? [37:06.650 --> 37:09.470] Well, it turns out that this one guy... [37:09.470 --> 37:10.630] Do I not have his name on here? [37:10.770 --> 37:12.050] That's really embarrassing, actually. [37:13.010 --> 37:14.310] I don't remember his name. [37:14.450 --> 37:14.930] I'll find it. [37:15.250 --> 37:20.010] This one guy wrote a HTML parser in JavaScript. [37:21.610 --> 37:22.630] This is useful. [37:23.670 --> 37:30.050] I may not be able to trust the browser's HTML parser, but JavaScript is a full programming language. [37:30.250 --> 37:31.010] It's Turing complete. [37:31.610 --> 37:32.730] I'll parse it. [37:32.910 --> 37:36.310] I will look inside and see, okay, there's some HTML here. [37:36.310 --> 37:38.630] This is an image tag. [37:38.970 --> 37:39.310] Cool. [37:39.510 --> 37:41.530] I'll create an image element. [37:41.850 --> 37:43.030] This is a bold tag. [37:43.270 --> 37:43.770] Cool. [37:43.930 --> 37:45.350] I'll create a bold element. [37:45.570 --> 37:46.290] This is a link. [37:46.450 --> 37:46.770] Cool. [37:46.870 --> 37:47.570] I'll create an anchor. [37:47.690 --> 37:50.510] But I want to make sure links can only go to certain locations. [37:50.850 --> 37:51.270] Okay. [37:51.470 --> 37:52.810] I control it. [37:52.930 --> 38:00.250] And every time I actually think, say I'm seeing a source, I'm going to push it right into the source element. [38:00.250 --> 38:03.850] I'm going to manipulate the tree directly. [38:04.230 --> 38:08.430] There's HTML parsing, but it's my HTML parsing. [38:08.570 --> 38:09.570] I control it. [38:09.690 --> 38:10.950] I know what it's doing. [38:11.190 --> 38:15.650] And so that allowed me to do that thing you saw earlier where I could say, image? [38:15.990 --> 38:16.270] Cool. [38:16.650 --> 38:17.430] Throw that in. [38:17.470 --> 38:19.390] And throw it in as an image. [38:19.390 --> 38:21.330] I'm creating the element and putting it in. [38:21.730 --> 38:22.210] Script? [38:22.730 --> 38:23.050] Nah. [38:23.210 --> 38:23.950] I don't do scripts. [38:24.170 --> 38:26.410] I'll take that text, but I don't do scripts. [38:26.410 --> 38:30.470] There is a package called Blueprint that came out a little while ago. [38:30.710 --> 38:33.590] And it actually says, you want to render a web page? [38:33.690 --> 38:35.470] There's no HTML parsing. [38:35.590 --> 38:40.490] There's just JavaScript, and we're going to push the entire thing through our engine. [38:40.930 --> 38:43.350] And it actually gets reasonable performance. [38:44.390 --> 38:45.550] Now there's a note. [38:45.730 --> 38:48.890] And the note is, security is quantized. [38:49.150 --> 38:54.350] There are tags you can push into the browser and know what they're going to do. [38:54.350 --> 38:59.810] You can't push a script tag into a browser and predict what the script is going to do. [39:00.390 --> 39:02.030] Programming languages are Turing complete. [39:02.390 --> 39:10.030] If you think you're going to know, or at least JavaScript is, if you think you can predict in advance what JavaScript is going to do, eh, you're wrong. [39:12.410 --> 39:17.710] So, how we're actually... now I want to switch to how this is actually implemented. [39:17.710 --> 39:29.410] And the reason why I want to talk about how it's implemented is, ultimately, I want people to try to find bugs, so I don't spend years talking about this, and find out, oh wait, that didn't work. [39:29.830 --> 39:36.890] So, right now, the only way we can do this stuff is through the mechanism of eval. [39:37.650 --> 39:38.130] Evaluation. [39:39.530 --> 39:45.990] eval takes a bunch of code and just says, okay, I'm going to run it. [39:46.170 --> 39:49.630] I'm going to compile this code and I am going to execute it. [39:49.810 --> 39:53.250] It is a very common thing in scripting languages to see. [39:53.250 --> 40:02.150] So, the idea is that the programmer writes, select star from table where fname equals fname, and country equals country, and x equals x, with those little carrots. [40:03.230 --> 40:07.770] What that is expanded into is a small batch of code. [40:08.190 --> 40:19.830] Return select star from table where fname equals b64d, and then the Base64 encoded version of fname, and country equals b64d, and then the Base64 encoded version of country, and so on. [40:19.830 --> 40:23.790] We take this batch of code and we evaluate it. [40:23.950 --> 40:34.010] And that evaluation, the output of this dynamically generated small program, is in fact select star from table with all the Base64 encoded stuff. [40:36.330 --> 40:39.950] There are languages that do not have eval. [40:40.050 --> 40:43.430] And most notably, that would be Java and C-sharp. [40:43.710 --> 40:54.930] We actually can still do this sort of stuff, but we have to do it using string concatenation, or various other kinds of sort of inline syntaxes that aren't so much interpolation. [40:55.490 --> 40:56.710] Actually, let me clarify. [40:57.150 --> 41:07.950] Java and C-sharp not only cannot dynamically compile and execute code, at least not efficiently, they also don't provide a way to easily inline refer to variables. [41:08.150 --> 41:10.190] They really just want you concatenating. [41:10.310 --> 41:14.330] They really want you to say this plus that and this plus that and so on. [41:14.330 --> 41:22.010] So there are two ways of actually interfacing with these languages beyond just concatenation. [41:22.310 --> 41:28.090] The first way is a pattern where you use variable argument syntax. [41:28.410 --> 41:33.530] So you can write a function in both Java and C-sharp that takes a variable number of arguments. [41:33.530 --> 41:41.370] And what we do is we say, well, we have, you know, w.c and then the safe stuff, and the second argument is unsafe. [41:41.650 --> 41:45.770] And then the safe argument is wc'd, and the second argument is unsafe. [41:46.130 --> 41:51.430] The reason you mark your safe stuff rather than your unsafe stuff should be obvious. [41:51.430 --> 41:56.990] You want to make sure if someone forgets to encode, it breaks. [41:57.270 --> 42:03.550] If you forget to mark select star from foo where x equals, it's just not going to run. [42:03.730 --> 42:04.950] Your query will fail. [42:04.970 --> 42:09.710] And more importantly, it will fail very early in the development process. [42:10.790 --> 42:19.490] Another approach to take is to use what's called the builder pattern, where you say have a function, say the w function. [42:19.810 --> 42:23.870] And then you'd say code has, you know, w.code is this. [42:24.010 --> 42:25.170] And then .data is that. [42:25.310 --> 42:26.490] And then .code is this. [42:26.630 --> 42:27.830] And then .data is that. [42:28.430 --> 42:31.370] And then you take the whole thing and you mark it to string. [42:32.070 --> 42:37.050] There's a way of expressing queries that this actually looks a lot like called link. [42:37.310 --> 42:39.430] How many of you guys have ever seen link in your lives? [42:41.110 --> 42:48.350] Link is basically a way of porting database concepts to the grammar of C sharp. [42:48.730 --> 42:56.730] So you're basically writing database queries as if, you know, you're doing a normal C sharp-ish operation. [42:57.370 --> 42:58.370] Link is great. [42:58.650 --> 42:59.850] Link is a new language. [43:00.070 --> 43:01.210] It is very effective. [43:01.210 --> 43:07.430] If you can use it, it is much more likely to be secure than all the stuff that we've been dealing with in terms of SQL injection. [43:07.890 --> 43:11.530] That being said, SQL's been around for a long time. [43:11.530 --> 43:15.210] And believe it or not, is kind of awesome. [43:15.850 --> 43:23.210] So there are a lot of people who have a lot of knowledge on how to do expressive, intelligent things in SQL. [43:23.530 --> 43:26.630] We want those expressive, intelligent things to be secure. [43:26.810 --> 43:34.670] If I'm on a job and I advise to someone, you have a bunch of SQL injections, why don't you rewrite your entire application with link? [43:35.230 --> 43:36.990] I'm getting fired. [43:38.330 --> 43:40.510] So I got to figure out a way to do SQL. [43:40.750 --> 43:43.530] This allows this stuff to stay SQL. [43:46.430 --> 43:47.770] Tiny little hope announcement. [43:47.770 --> 43:50.930] I actually have working implementations of both of these in Java. [43:50.930 --> 43:54.930] So if you'd like to go ahead and play with this, let me know and I'll send you the code. [43:54.930 --> 43:57.370] This is actually working as of, you know, a week ago. [43:59.890 --> 44:01.470] So status quo. [44:01.890 --> 44:03.990] Let's talk about what doesn't work. [44:04.450 --> 44:09.570] Having string s equals select star from foo where x equals the escape value of s. [44:09.870 --> 44:14.770] If it worked, we wouldn't keep finding it wrong in the field. [44:15.110 --> 44:24.310] So the reason why this actually doesn't work is you can screw it up entirely and the code still functions. [44:24.730 --> 44:33.590] We need to have models where if you screw it up and implement it wrong, the fact that it's insecure also means that it's non-functional. [44:33.690 --> 44:36.370] And the fact that it's functional means that it's secure. [44:36.590 --> 44:41.430] I apologize for harping on this, but if there's one thing you take away from this talk, let it be that. [44:43.830 --> 44:47.790] Why is this such a pain in the ass to implement? [44:48.010 --> 44:49.610] And let me tell you, it really is. [44:49.610 --> 44:53.170] The programming languages do not want you doing this. [44:53.850 --> 44:57.270] It turns out there was a war in computer science. [44:57.870 --> 45:04.730] And not being an academic, I had no idea this war happened, but apparently there was a victor. [45:04.910 --> 45:11.710] And it has been, you know, wiping out the remnants of the defeated one for ages. [45:12.070 --> 45:16.910] The war is between the concept of lexical scope and dynamic scope. [45:16.910 --> 45:28.650] In lexical scope, when a function is compiled, it knows all the possible variables that it is going to need to have access to. [45:29.270 --> 45:39.010] Everything that it needs to know has been pushed into it, either as arguments, or as a global, or as whatever. [45:39.010 --> 45:41.950] But everything is explicitly known. [45:42.810 --> 45:45.090] Then there's dynamic scope. [45:45.390 --> 45:53.310] And in dynamic scope, you say, well, I'm running, and I've been instantiated by some other totally different piece of code. [45:54.010 --> 45:59.410] I might need to ask that totally different piece of code, hey, what's your foo variable? [45:59.950 --> 46:02.210] I might need to go back and look and find out. [46:02.370 --> 46:03.070] I don't know. [46:04.090 --> 46:08.310] There has been arguments for 20 years about which is right. [46:09.350 --> 46:11.390] Lexical scope one. [46:11.710 --> 46:15.850] And one to a degree that every language that has come out... [46:32.490 --> 46:33.270] Right. [46:34.910 --> 46:35.690] Right. [46:35.830 --> 46:46.930] So what's been happening over the last couple of years has been a systematic removal of anything that could be hacked into making dynamic scope work. [46:47.210 --> 46:56.590] You don't have macros in programming languages, meaning the ability to say, I know I wrote this string, but what I really meant was this string. [46:56.930 --> 46:58.050] That's been removed. [46:58.330 --> 46:59.950] The ability to even... [46:59.950 --> 47:01.190] This is actually kind of crazy. [47:02.610 --> 47:10.990] They went ahead and in the actual implementations, they're like, say, of Java and C Sharp, they removed the names. [47:11.390 --> 47:23.230] You, in a theoretical world, could totally have hacked your way through the stack and said, okay, let's go ahead and go into this part of the active runtime environment and get this variable. [47:23.530 --> 47:25.210] I know because I tried to do it. [47:26.330 --> 47:29.010] Yeah, they actually remove the names. [47:29.190 --> 47:33.230] They're like, oh, I've got my third argument and I've got my eighth argument. [47:33.390 --> 47:34.570] Like, so what's the name of it? [47:34.690 --> 47:35.850] I'm not telling. [47:37.490 --> 47:37.970] Bastards! [47:41.190 --> 47:42.890] So, this is kind of weird. [47:44.230 --> 47:44.950] So, okay. [47:45.970 --> 47:47.670] Yes, there's risk to eval. [47:47.670 --> 47:50.050] I'm not saying it's a great approach. [47:50.250 --> 47:53.450] I have many, many better ways that I'd like to see doing it. [47:53.590 --> 47:57.510] And yes, in general, lexical scope is right. [47:57.930 --> 48:00.930] But, this is what it comes down to. [48:01.450 --> 48:11.070] Every major programming language used to develop web applications is exposing the same vulnerabilities in the same ways. [48:11.070 --> 48:16.890] There is something wrong with the way that programming languages are being designed. [48:17.150 --> 48:31.470] And we, as the people actually breaking these languages consistently, have to start being able to use our knowledge and our experience with their failures to get those failures remediated. [48:31.850 --> 48:37.530] Put simply, language design needs to be informed by the findings of penetration testing. [48:37.530 --> 48:40.450] It's certainly informed by performance. [48:40.730 --> 48:42.950] It's certainly informed by usability. [48:43.970 --> 48:46.930] Memory safety, we think it came from us. [48:47.030 --> 48:47.250] No. [48:47.650 --> 48:55.830] Memory safety came because the reliability guys were like, the code keeps crashing because devs can't handle malloc and free. [48:56.510 --> 48:58.950] What are we going to do to fix that? [48:59.090 --> 49:00.630] And that's how we got memory safety. [49:00.630 --> 49:03.850] We got it as a gift to us. [49:04.250 --> 49:11.110] You know, web applications have a lot of canonical flaws, but use after free tends not to be one of them. [49:13.190 --> 49:23.850] I think the experience of all of these injection flaws has taught us languages need the ability to write functions that run in the present scope, not a child scope. [49:23.850 --> 49:30.330] And if you're an old school programming guy, you're going to be terrified by my next slide. [49:30.570 --> 49:34.890] It looks just a little like Lisp was right. [49:37.150 --> 49:38.510] Not about everything. [49:38.510 --> 49:40.170] Those parentheses are retarded. [49:41.450 --> 49:42.130] Deal. [49:43.410 --> 49:48.950] But, yeah, it actually turns out that Lisp had a point about scoping. [49:50.750 --> 49:52.810] I kind of have a theory about JavaScript. [49:53.390 --> 49:58.150] Because no one thought JavaScript was a serious language, they just let it have everything. [49:58.550 --> 50:04.910] And, of course, for most of JavaScript's existence, this meant JavaScript was a horrifying language. [50:05.250 --> 50:07.610] And then, over time, people were like, wait a second. [50:07.830 --> 50:11.510] This can do everything, including really useful stuff. [50:11.770 --> 50:18.190] And so we've seen over the years all these dialects of JavaScript form where JavaScript gets to be, you know, really, really useful. [50:18.190 --> 50:21.150] You know, there's the JavaScript, the good parts. [50:21.350 --> 50:24.410] And I kind of expect to see this happen to Haskell at some point as well. [50:26.550 --> 50:28.450] So, let's talk about risks. [50:28.590 --> 50:34.590] And by risks, I mean, if you're going to try to own this, here are my suggestions for what to look at. [50:34.970 --> 50:39.630] There are three things that can go wrong with any defensive technology. [50:40.270 --> 50:43.170] First, it might not work. [50:43.170 --> 50:49.730] And none of this mealy-mouth, well, it depends on your threat model and how smart you think the attacker is. [50:49.910 --> 50:51.370] No, that's bullshit. [50:51.810 --> 50:54.290] It either works or it doesn't. [50:54.650 --> 51:03.550] So, first thing that might happen is that I may think that the browser has all these great restrictions on text content. [51:03.550 --> 51:04.090] But you know what? [51:04.110 --> 51:04.770] I'm wrong. [51:05.010 --> 51:08.910] Or I might think the database doesn't do things that it actually does. [51:08.910 --> 51:12.070] So, that's the first class of failure. [51:12.290 --> 51:14.650] It is not at all the only class. [51:15.090 --> 51:18.510] The second class of failure is it doesn't work in the field. [51:18.830 --> 51:26.350] Meaning, it's great in theory, but when developers try to use it, it's too hard, it's too obtuse, it's too slow, it's too whatever. [51:26.710 --> 51:28.010] This matters. [51:28.410 --> 51:32.770] So, that's the second thing that can make a defensive technology not actually work. [51:32.770 --> 51:40.170] The final thing that might mean that this defensive technology is problematic is it has side effects. [51:40.430 --> 51:44.250] Meaning, it fails some of the other first class engineering requirements. [51:44.250 --> 51:46.390] It's too slow or unstable or hard to deploy. [51:47.230 --> 51:48.790] Actually, that might seem redundant. [51:49.030 --> 51:50.810] So, let me be very clear about the second class. [51:51.050 --> 51:56.870] The second class is that developers are going to try to write it, but they're going to screw something up. [51:57.070 --> 51:58.990] Something in the syntax is too difficult. [51:58.990 --> 52:01.770] It's too hard for them to mentally wrap their mind around. [52:02.530 --> 52:07.190] I'm looking for analysis on what might go wrong on any of these three classes. [52:08.430 --> 52:11.230] So, let's talk about what actually looks... [52:11.230 --> 52:15.010] how this has actually survived our own attacks. [52:16.770 --> 52:21.610] There doesn't seem to be any way to get SQL injection to work through that Base64 layer. [52:23.350 --> 52:31.530] The performance seems okay, but more important, yeah, it really does look like you get safe strings going into the function, you get safe strings coming out. [52:32.550 --> 52:37.250] There are no known flaws when putting arbitrary text into a text content field for a span. [52:37.450 --> 52:41.230] I've not found any way to actually get script to execute. [52:41.610 --> 52:50.950] And there are no known flaws when creating arbitrary HTML as long as there's a safe subset of things that you're injecting in. [52:50.950 --> 52:58.810] Meaning, I don't care what kind of text goes into the source element of an image, it's not going to run script. [53:01.850 --> 53:02.490] Eval. [53:02.870 --> 53:05.730] Eval absolutely adds some risk. [53:06.530 --> 53:09.490] There are people who say, well, I turn off Eval on my server. [53:09.690 --> 53:10.650] You know what I reply to that? [53:11.030 --> 53:11.270] Yeah. [53:11.530 --> 53:13.410] Did you see month of PHP bugs? [53:14.810 --> 53:20.670] PHP is just not going to be a safe programming language if an attacker can run arbitrary PHP. [53:20.990 --> 53:24.030] Like, it's just not a memory-safe environment. [53:24.030 --> 53:31.490] So, at the point where an attacker has any code running, they don't need Eval to obfuscate stuff. [53:31.490 --> 53:35.050] They can just smash the PHP stack, thank you very much. [53:35.230 --> 53:39.030] I'm sorry, I wasn't even trying to crash PHP. [53:39.510 --> 53:39.650] Okay? [53:40.110 --> 53:40.990] We'll leave it at that. [53:42.810 --> 53:49.070] What is real, though, is that Eval, in this context, can make programmer errors a lot more severe. [53:49.390 --> 53:59.830] So, if the correct way to express a piece of secure code would be, eval b select star from foo where x equals caret caret x. [54:00.170 --> 54:03.370] If the developer, instead, goes halfway. [54:03.630 --> 54:08.250] They say, eval b select star from foo where x equals dollar sign x. [54:08.410 --> 54:13.870] If they put in the native interpolator rather than my interpolator, oh, crap. [54:14.190 --> 54:20.950] Now, not only do I have SQL injection against the back end, I have code execution against the front end. [54:20.950 --> 54:22.170] Not good. [54:22.950 --> 54:30.610] So, that is, as a base mitigation, why I switched from dollar sign exclamation point foo to caret caret foo. [54:30.730 --> 54:32.950] To increase the difference. [54:33.310 --> 54:36.350] This is actually von Heuser from THC. [54:36.530 --> 54:38.910] He actually made me realize, no, I gotta change that. [54:40.670 --> 54:42.250] Managing the risk of the eval. [54:42.610 --> 54:44.250] Now, we have an expansion function. [54:44.430 --> 54:46.810] That's this b function right here, eval b. [54:47.490 --> 54:52.170] This function is in a position to see what it is expanding. [54:52.730 --> 54:55.810] So, the first thing it can do is it can actually look and say, hey, wait a second. [54:55.870 --> 54:59.090] Am I expanding in a way that's gonna lead to code execution? [54:59.310 --> 55:00.270] You can do that. [55:01.410 --> 55:03.210] It can be aware of SQL grammar. [55:03.410 --> 55:08.730] So, it can say, I am only going to emit an actual safe SQL statement. [55:08.730 --> 55:17.110] And I'm gonna make sure that anything that is the right hand comparison, meaning x equals possible attacker supplied variable. [55:17.410 --> 55:20.490] I'm gonna make sure that that is always encoded. [55:20.650 --> 55:26.630] And if I ever get a time where it's not encoded, it better at least be in this safe one function. [55:26.830 --> 55:29.370] Or I'm just going to return blank. [55:30.290 --> 55:41.030] Meredith Patterson put together some code called dejector that actually does this sort of, before I send it to the database, let's go ahead and do a grammatical parse and make sure it meets something that we want. [55:41.650 --> 55:45.290] Dejector, we're looking at actually moving it into this what I call b function. [55:46.230 --> 55:57.850] And finally, and this is kind of hideous, okay, I can't go back in the stack and say, hey, I'm in the middle of, you know, function 10, 10 levels deep in PHP. [55:58.210 --> 56:04.870] Let's make sure I was called and what I was called with actually had me, you know, correctly handling interpolation. [56:06.090 --> 56:07.810] I can't do that in the stack. [56:08.070 --> 56:13.690] But what I can do is say, what's the line of code that called me and from what file? [56:14.550 --> 56:15.190] Huh? [56:16.210 --> 56:16.850] Huh? [56:17.550 --> 56:18.750] Yeah, it's a terrible idea. [56:18.870 --> 56:19.230] Don't do it. [56:20.710 --> 56:23.410] Just because it works doesn't make it a good idea. [56:25.830 --> 56:32.790] What only sort of works is that in some languages, single quotes turn off native interpolation. [56:32.970 --> 56:38.410] Meaning dollar sign foo only works if you have double quotes and single quotes means don't do it. [56:38.730 --> 56:41.470] Just pass that down to the underlying function. [56:42.130 --> 56:47.510] So the thinking is that you require eval be single quote, double dollar sign foo. [56:47.950 --> 56:52.450] The problem is, is single quotes look a lot like double quotes. [56:53.270 --> 56:55.210] So we have a policy here. [56:55.370 --> 57:09.410] And I can't rag on policy for development shops because at the end of the day, the most effective way that I've ever seen code get secure has been through compiler or some sort of enforced policy. [57:09.410 --> 57:19.410] You know, when you hear about secure development life cycles and SDL and all those things, what they're basically saying is, yeah, there's a lot of crap you could write. [57:19.710 --> 57:21.730] Here's what will actually let you check in. [57:21.930 --> 57:25.250] I will say I've seen that be really effective on Microsoft code. [57:25.250 --> 57:26.250] Oh my God. [57:28.410 --> 57:30.030] Absolutely the large shops can do this. [57:30.170 --> 57:34.510] I'm not convinced I could ever make a small, you know, the dev ever implement this. [57:36.110 --> 57:39.930] Performance wise, eval is slower than compiled code. [57:39.930 --> 57:42.310] So it depends how much you're trying to eval. [57:42.310 --> 57:46.070] It is possible to cache these transformations. [57:46.490 --> 58:01.350] One of the nice things about retaining the boundary between code and data is all of a sudden making data nothing and blank and just normalizing it all to here's the canonical query, whatever may come in, cache this. [58:01.590 --> 58:03.350] You can actually do that now. [58:03.350 --> 58:04.630] And it's actually much easier. [58:04.850 --> 58:08.930] So if databases aren't already doing this, we can actually do that. [58:09.550 --> 58:11.350] And it works the other way as well. [58:12.970 --> 58:14.970] It has become the situation where... [58:15.690 --> 58:24.150] So you might say, Dan, you know, why is it that it's fast to go through directly manipulating the JavaScript DOM instead of writing HTML? [58:24.530 --> 58:26.610] Isn't everything normally writing HTML? [58:26.610 --> 58:27.990] So isn't that the normal case? [58:28.470 --> 58:33.510] Well, so we've got Facebook and Gmail and they've totally changed the way that browsers are implemented. [58:33.770 --> 58:37.930] So IE6 was really slow if you tried to take the backdoor approach. [58:37.930 --> 58:41.690] But everything else, yeah, you just get to blast things in. [58:41.870 --> 58:48.790] And what's kind of cool is, is that you can say, here is an object and it has all of these possible fields that are going to be filled in. [58:48.930 --> 58:56.450] You know, image sources and this and that, you can actually cache the secure object and then fill stuff in as needed. [58:56.950 --> 59:00.010] And it works very well and it's how Gmail and Facebook actually work. [59:00.710 --> 59:03.290] So if there's anything else, I don't know. [59:03.910 --> 59:07.050] I've done everything I can do to make this actually interesting. [59:07.410 --> 59:09.430] We're still working on this project, but there's more. [59:10.550 --> 59:12.630] It's not two months, like two weeks actually. [59:14.390 --> 59:17.650] What we're doing now is not working. [59:17.870 --> 59:18.990] I'm going to say it again. [59:19.430 --> 59:23.290] What we're doing now is not working. [59:24.210 --> 59:29.710] Code is getting a little more secure, but not that much and not enough. [59:31.270 --> 59:36.770] We need to start having discussions on how we're going to write secure code for the next decade. [59:36.950 --> 59:39.150] What sort of advice we're going to give. [59:39.530 --> 59:45.830] The difference between good advice and bad advice is, does it work? [59:46.030 --> 59:47.290] And can people do it? [59:47.470 --> 59:49.950] And I hope we as a community can give good advice. [59:50.390 --> 59:51.270] That's what I got. [01:00:03.370 --> 01:00:07.230] So I have no idea how much time I have, but I am open for questions if there's time. [01:00:08.210 --> 01:00:08.530] Is there? [01:00:08.870 --> 01:00:09.090] Yep. [01:00:09.490 --> 01:00:09.750] All right. [01:00:09.810 --> 01:00:10.610] There's time for questions. [01:00:11.690 --> 01:00:12.910] Come on up and ask me something. [01:00:16.040 --> 01:00:16.400] Okay. [01:00:16.640 --> 01:00:17.440] Question for you. [01:00:17.800 --> 01:00:18.260] All right. [01:00:18.340 --> 01:00:18.800] Where are you? [01:00:18.900 --> 01:00:19.520] I can't see you. [01:00:19.720 --> 01:00:20.100] Middle mic. [01:00:20.100 --> 01:00:20.560] Oh, there you are. [01:00:20.640 --> 01:00:20.760] Okay. [01:00:21.760 --> 01:00:26.760] One of the security suggestions that's often given is to turn off JavaScript in the browser or use something like NoScript. [01:00:26.760 --> 01:00:31.680] And what you're suggesting requires JavaScript beyond, or you get a blank page. [01:00:32.500 --> 01:00:35.680] Could you sort of comment on the difference between the two? [01:00:36.000 --> 01:00:37.500] We're lying to ourselves. [01:00:38.140 --> 01:00:39.200] We do that a lot. [01:00:41.520 --> 01:00:44.780] If you want to browse the web, you're using JavaScript. [01:00:45.680 --> 01:00:53.980] If the approach is, well, when you get to a site that isn't working by JavaScript, you have to click OK to the pop-up. [01:00:54.100 --> 01:00:55.080] Let me ask you something. [01:00:55.080 --> 01:01:01.200] Why is it a problem when Vista gives you a pop-up and not a problem when your browser gives you a pop-up? [01:01:01.380 --> 01:01:06.060] We need to secure the web when JavaScript is active because you know what? [01:01:06.340 --> 01:01:10.320] Users are browsing the web with JavaScript active. [01:01:10.660 --> 01:01:11.600] It's not a maybe. [01:01:11.820 --> 01:01:12.840] It's not a kinda. [01:01:13.300 --> 01:01:15.040] It's just the way it is. [01:01:16.700 --> 01:01:17.260] Sure. [01:01:17.600 --> 01:01:19.160] I know it needs to be that way. [01:01:19.380 --> 01:01:19.940] Yes. [01:01:19.940 --> 01:01:28.020] You're kind of in a catch-22 situation where if the website that you're browsing has been secured in the way you're describing, turning JavaScript on is a good idea. [01:01:28.200 --> 01:01:35.500] If it hasn't, then turning JavaScript off is a good idea and getting from one to the other is a problem. [01:01:35.500 --> 01:01:40.360] So here's a funny thing, and actually CP from 949 pointed this out as well. [01:01:41.380 --> 01:01:47.000] You may have someone come to your site with JavaScript disabled and then, oh my god, this site doesn't work. [01:01:47.280 --> 01:01:55.620] Well, it turns out you can actually, once JavaScript is disabled, it is actually safe to hand them all the stuff that would normally be cross-site scriptable. [01:01:56.080 --> 01:01:58.220] Because JavaScript is disabled. [01:01:58.940 --> 01:02:17.660] So, you can very easily dynamically detect, oh, I'm using someone who, I'm talking to someone who has JS disabled, let's give them the other version of this page, and you don't need to be as worried about filtering because the user has taken the I'll filter this for you approach. [01:02:18.480 --> 01:02:19.340] Kind of neat. [01:02:20.300 --> 01:02:21.200] Next question. [01:02:22.100 --> 01:02:32.840] All right, so the strategy you're suggesting, I guess, has very obvious performance implications on the JavaScript side, like eval undoes all the VM sort of optimizations. [01:02:33.300 --> 01:02:35.560] And I guess the second part of that is... [01:02:35.560 --> 01:02:36.380] Oh, well, hang on. [01:02:36.480 --> 01:02:39.000] There's only eval on the database side. [01:02:39.200 --> 01:02:41.940] There's no eval in the JavaScript side. [01:02:42.140 --> 01:02:58.000] What happens is the back end, it might be evaling, but the front end is only seeing I a span, and now I've got to decode the span, and the decode finds through a constant time lookup, and then that has actually been optimized by the browser developers. [01:02:58.180 --> 01:02:58.940] But wait a second. [01:02:59.080 --> 01:03:03.280] If it were done by a Ruby VM, it would suffer the same lack of performance optimizations, right? [01:03:04.300 --> 01:03:04.740] Depends. [01:03:04.740 --> 01:03:07.040] What I'm sending back is... [01:03:07.040 --> 01:03:08.980] No because I would be... [01:03:08.980 --> 01:03:14.060] If I can if I wanted, I could basically have my select out of the database include a B64E. [01:03:14.220 --> 01:03:14.660] Right. [01:03:15.860 --> 01:03:16.480] So... [01:03:16.480 --> 01:03:25.420] The idea is like, if it does, and most people are not writing SQL anymore, they're writing Rails or Django, whatever they're using. [01:03:25.420 --> 01:03:35.680] So, what do framework developers do to address this big problem in a generic way that sort of doesn't make performance decisions for all the application developers? [01:03:35.960 --> 01:03:44.720] Okay, so the first thing is, if you have devs that are expressing their database queries in the native programming language, great. [01:03:45.320 --> 01:03:49.760] I want to be clear, there's no room for religion in defense. [01:03:50.240 --> 01:03:55.260] Like, you don't just say you've got to use, you know, this language or that language or whatever. [01:03:55.420 --> 01:03:58.160] If you've got people migrated, wonderful. [01:03:58.620 --> 01:04:01.820] There's a whole bunch of SQL out there still, though. [01:04:02.220 --> 01:04:15.940] And there's a whole bunch... if not SQL, there's still a whole bunch of HTML being emitted without any kind of sane way of separating what comes from the framework and what comes from the attacker. [01:04:16.200 --> 01:04:22.840] I'm more than happy to have this only exist on the how do we render HTML safely side. [01:04:22.840 --> 01:04:29.780] But for the people who are still actually writing SQL, and there are quite a few, let's give them a way to do it safely. [01:04:31.160 --> 01:04:36.480] Yeah, you talk about wanting to be able to execute functions in the local context. [01:04:37.440 --> 01:04:48.960] I'm sure you've at least thought of this, but using macros through something like CPP that gets... does a transform on your code before the interpreter or compiler hits it. [01:04:49.000 --> 01:04:49.700] Why not do that? [01:04:49.700 --> 01:04:53.580] Because they removed macros from every language that's come out since CPP. [01:04:53.860 --> 01:04:58.200] Yeah, but you can re-implement it without too much trouble. [01:04:58.560 --> 01:05:03.060] So the problem is, is that... so this has actually come up. [01:05:03.240 --> 01:05:05.880] What if we made this stuff like IDE plugins? [01:05:06.140 --> 01:05:08.900] What if we made this stuff, you know, implemented it in the build script? [01:05:08.900 --> 01:05:23.100] And the feeling is, is that... you get into real maintainability problems if your code has to go through transformation outside of the context of the programming language. [01:05:23.500 --> 01:05:30.120] Like, you see these situations where languages are chained on chains and chains, and I tell you, it's made... [01:05:31.780 --> 01:05:35.660] So, GNU, automake, and autoconf is kind of amazing. [01:05:36.000 --> 01:05:37.040] Like, it works. [01:05:37.220 --> 01:05:40.960] The output of these things compiles all over the place over long periods of time. [01:05:41.120 --> 01:05:49.400] But I don't think I've ever been on a project where I haven't spent as much time fighting with autoconf and automake as I have with the code itself. [01:05:49.400 --> 01:05:55.060] So, I'm a little allergic to, hey, why don't we do something outside the language? [01:05:55.380 --> 01:06:00.400] I think the right thing to do is to have the languages give us a way to... [01:06:01.160 --> 01:06:08.300] Not all the time, but sometimes I need a way to say, this function has access to the variables of its parent. [01:06:08.580 --> 01:06:09.320] Make it work. [01:06:10.320 --> 01:06:11.040] Thank you. [01:06:11.400 --> 01:06:11.960] No worries. [01:06:14.340 --> 01:06:20.440] So, you described dynamic versus static scoping as a war between factions. [01:06:21.080 --> 01:06:24.040] That's actually not quite the right history, as far as I'm aware. [01:06:24.280 --> 01:06:24.860] Tell me more. [01:06:25.180 --> 01:06:29.400] So, originally, Lisp was the dynamically scoped language. [01:06:29.560 --> 01:06:29.780] Okay. [01:06:30.260 --> 01:06:32.380] That was actually an implementation bug. [01:06:34.440 --> 01:06:35.360] It turns out... [01:06:35.360 --> 01:06:36.280] It's not a bug, it's a feature. [01:06:36.540 --> 01:06:38.260] Right, it turns out that it has some nice features. [01:06:38.260 --> 01:06:48.460] But, the canonical way of doing dynamic scoping, which is to say, if you just follow what Lisp did so many years ago, actually has a number of reliability problems. [01:06:48.800 --> 01:06:52.140] Because you can write code where variables escape their closure. [01:06:52.760 --> 01:06:58.840] And the result of that is that your program crashes by manipulating stray pointers in a memory-safe language. [01:06:59.160 --> 01:07:00.760] Right, that's not something we like. [01:07:00.900 --> 01:07:04.540] So, the war was won mostly under the banner of reliability. [01:07:05.820 --> 01:07:13.920] How would you reconcile the fact that dynamic scoping decreases reliability with the fact that you seem to be able to increase security with it? [01:07:14.400 --> 01:07:16.840] So, the idea is not... [01:07:17.740 --> 01:07:19.180] That you can do... [01:07:19.180 --> 01:07:21.240] That you can move in a million directions. [01:07:21.840 --> 01:07:23.000] And that's a problem. [01:07:23.160 --> 01:07:25.160] Does not mean you should move in zero directions. [01:07:25.500 --> 01:07:27.220] Because that also is a problem. [01:07:27.220 --> 01:07:31.220] The idea is that I shouldn't have to use eval... [01:07:31.840 --> 01:07:33.060] So, here's what's going on. [01:07:33.300 --> 01:07:37.920] I get a variable named inside of a string. [01:07:38.320 --> 01:07:43.980] I don't know, until that variable comes in, what I need to dereference. [01:07:44.300 --> 01:07:54.520] I need the ability to actually dereference that value without having to go ahead and force all values in. [01:07:55.480 --> 01:07:56.040] It's... [01:07:57.900 --> 01:08:02.700] It's an interesting question of how you do dynamic scoping safely. [01:08:03.260 --> 01:08:09.320] If for no other reason, that you can also get into the situation where the attacker can inject random other variables as well. [01:08:10.420 --> 01:08:11.560] So, here's the deal. [01:08:11.800 --> 01:08:18.260] We want to make sure that the developer can write the string that dereferences an arbitrary variable. [01:08:18.260 --> 01:08:23.420] We also want to make sure an attacker cannot write the string that dereferences an arbitrary variable. [01:08:23.600 --> 01:08:29.500] And we absolutely, absolutely want to avoid the lisp situation where, you know, random pointers get overwritten. [01:08:29.800 --> 01:08:31.220] I think it's possible. [01:08:31.220 --> 01:08:39.740] And more importantly, I think it's necessary because all these programming languages are emitting the same failure class. [01:08:39.980 --> 01:08:46.440] That sort of absolute consistency means there is a problem with the way we're writing languages in general. [01:08:47.340 --> 01:08:47.940] Thank you. [01:08:49.080 --> 01:08:49.760] Next question. [01:08:51.780 --> 01:08:56.680] Hey, so you presented the two different ways of writing this new query language. [01:08:57.020 --> 01:08:58.180] For Java, you mean? [01:08:58.360 --> 01:08:59.620] Not for JavaScript. [01:08:59.760 --> 01:09:00.380] For the server side. [01:09:00.520 --> 01:09:02.400] The one using eval and the chaining one. [01:09:02.620 --> 01:09:02.840] Yeah. [01:09:03.060 --> 01:09:13.400] Why even bother with the one using eval since it seems to have a lot of... a few little things that people don't like, when the chaining one solves the problem of not being able to access the variables in the parent scope? [01:09:16.640 --> 01:09:18.000] The... what's it called? [01:09:19.180 --> 01:09:22.540] The eval is more usable and more likely to get adoption. [01:09:23.460 --> 01:09:24.020] Okay. [01:09:24.020 --> 01:09:25.300] Oh, you see, that matters, right? [01:09:25.580 --> 01:09:30.580] Like, hey, you know, devs prefer string interpolation to string concatenation. [01:09:31.240 --> 01:09:34.860] If we can give them either in a safe way, great. [01:09:35.380 --> 01:09:38.080] I've actually implemented both in both languages. [01:09:38.080 --> 01:09:41.420] So I have the PHP version that is doing string concatenation as well. [01:09:42.080 --> 01:09:44.280] But, you know, let me pull it up here. [01:09:44.780 --> 01:09:45.020] Yeah. [01:09:45.280 --> 01:09:50.400] I can totally tell devs to do w code and, you know, dot code and dot data and dot code and dot data. [01:09:50.620 --> 01:09:53.060] And I can also tell them to do this variable argument thing. [01:09:53.260 --> 01:09:54.440] I can do this. [01:09:54.600 --> 01:09:57.940] But, you know, it's a lot easier for me to tell them to do this. [01:09:58.320 --> 01:10:01.440] Write it like you want to in the insecure way and I'll deal with it. [01:10:02.560 --> 01:10:02.960] Okay. [01:10:03.100 --> 01:10:03.500] Fair enough. [01:10:05.340 --> 01:10:06.340] Any other questions? [01:10:08.040 --> 01:10:08.520] Cool. [01:10:08.660 --> 01:10:09.340] You guys have been great. [01:10:23.350 --> 01:10:23.970] I'm hungry.