[00:00.000 --> 00:05.200] He's from Hacktivismo, and he's doing proactively secure programming techniques. [00:05.420 --> 00:06.180] I'll let you have it. [00:06.920 --> 00:07.480] All right, thank you. [00:08.680 --> 00:12.840] Yes, as you mentioned, my name is Joe Salvatore Testa from Hacktivismo. [00:14.020 --> 00:17.160] Hacktivismo is a human rights and technology group. [00:17.200 --> 00:19.880] It is a subdivision of the Cult of the Dead Cow. [00:20.760 --> 00:33.800] What we focus on, we're a special projects group, we focus on researching and implementing circumvention, technology designed to defeat state-sponsored censorship of the Internet. [00:34.320 --> 00:39.160] We have a major announcement coming up here at HOPE tomorrow, 1 p.m. [00:39.840 --> 00:42.520] It's going to be in the unscheduled speaker track. [00:43.060 --> 00:44.460] We're promoting it heavily. [00:44.880 --> 00:45.820] Please show up. [00:46.600 --> 00:49.860] We're going to be releasing a major project tomorrow. [00:51.680 --> 00:55.040] One result of that project is this presentation. [00:55.040 --> 01:00.220] For the last three and a half years, I've been working on this project, an unnamed project. [01:00.560 --> 01:10.220] And along the way, I've been thinking here and there little details about proactive programming techniques. [01:10.240 --> 01:12.120] And that's what I'd like to share with you today. [01:21.330 --> 01:28.710] First, a lot of the techniques deal with, in the context of direct memory languages, so let me define that first. [01:28.710 --> 01:34.850] Direct memory languages are those that allow direct memory, direct access to memory without any bounds checking. [01:35.350 --> 01:40.290] Those are the older languages, Assembly, C, C++. [01:41.250 --> 01:44.670] There's no bounds checking when you access arrays for reading or writing. [01:44.930 --> 01:46.530] It's just done directly in memory. [01:49.050 --> 01:57.050] So I guess non-direct memory languages would be those that allow access only if it falls within the buffer's range. [01:57.170 --> 02:00.670] So it has to do bounds checking every single time you read or write. [02:01.370 --> 02:05.270] Examples are the newer languages, Java, PHP, Perl, Python, and others. [02:12.930 --> 02:18.530] Okay, so the first point I'd like to point out is don't use direct memory languages. [02:18.810 --> 02:20.950] There's little need to use them anymore. [02:21.370 --> 02:28.390] The newer languages such as Java, PHP, Perl that I just mentioned, those are better for several reasons. [02:28.910 --> 02:31.090] Faster development time, for one. [02:33.910 --> 02:37.090] And due to the bounds tracking, they're immune to buffer overflows. [02:40.010 --> 02:44.170] Mostly, I mean, in the code that you write, you'll be immune to buffer overflows. [02:44.410 --> 02:51.910] But I remember there was one time in Java, the Java from Sun was vulnerable to a buffer overflow. [02:53.270 --> 03:00.490] But that is a problem in very specific code that can be fixed in one spot, not in, you know, thousands of projects. [03:01.330 --> 03:05.710] So the consequences of bounds checking, one, slower execution time. [03:05.870 --> 03:11.690] Every time you access an array, reading or writing, it has to be done. [03:11.690 --> 03:12.730] So that slows it down. [03:12.850 --> 03:16.310] The benefits, like I said, faster development time and immunity from buffer overflows. [03:16.730 --> 03:18.530] So that's why you shouldn't use them anymore. [03:19.850 --> 03:21.670] There is a... [03:22.170 --> 03:25.130] It is tempting to still use C and C++, okay? [03:25.210 --> 03:26.330] I'm a hard core programmer. [03:26.510 --> 03:27.430] I like C. [03:27.630 --> 03:28.990] I like the power it gives you. [03:29.170 --> 03:31.110] But you have to fight that, okay? [03:33.390 --> 03:34.870] You have to fight that urge. [03:35.150 --> 03:36.030] Get it out of your system. [03:36.650 --> 03:39.770] Try to use these newer languages when you can. [03:47.800 --> 03:57.300] So the bottom line is, if you need to use these direct memory languages, use proactively secure programming techniques to prevent buffer overflows and other logic errors. [03:58.740 --> 04:00.740] So the question is, what is proactive? [04:01.220 --> 04:04.640] And that I'm talking about using... [04:04.640 --> 04:09.580] It's an application of defense in depth at the code level. [04:09.760 --> 04:14.900] It's an implementation, an actual instantiation of the defense in depth principle at the code level. [04:21.500 --> 04:24.920] I should give a quick buffer overflow example. [04:25.100 --> 04:29.300] This is by far a definitive guide on buffer overflows, but... [04:31.500 --> 04:33.140] Let's look at this program here. [04:35.300 --> 04:39.940] You have two variables, one called authenticated, which is an integer set to zero. [04:40.780 --> 04:43.940] You have a character buffer, which is 16 bytes long. [04:45.780 --> 04:54.560] Defined in that order, the GCC compiler will place buff in low memory and auth in high memory. [04:54.560 --> 05:09.840] I don't think that that is a requirement, a C NCC requirement, but that seems to be pretty common with compilers to put variables defined later in low memory. [05:10.280 --> 05:23.320] So the program copies from the command line, AV1, blindly into BUF, the buff, 16 byte character array, and checks to see that buff is equal to password. [05:23.780 --> 05:26.820] If so, it sets authenticated to 1. [05:28.560 --> 05:40.940] Later we have some code that checks authenticated and if it's non-zero, which is 1, it will print supercalifragilistic, meaning you authenticated. [05:41.200 --> 05:42.600] Otherwise it will print no words. [05:45.390 --> 05:49.070] So at the top, we run this program with the wrong password and it will say no. [05:49.690 --> 05:52.290] We run it with the right program and it will say yes. [05:53.470 --> 05:58.950] And then, remember, we didn't do any bounds checking on the string copy into BUF. [05:59.290 --> 06:06.350] So if we put a whole bunch of characters on the command line, that will be copied into BUF blindly. [06:07.730 --> 06:11.510] You do it once, we didn't add enough, it says novers. [06:11.850 --> 06:15.570] We do a little bit more, and all of a sudden, we authenticated. [06:15.570 --> 06:20.070] And what happened in memory is illustrated in that picture right there. [06:21.690 --> 06:30.330] The X's started out in BUF, but they overflowed over in the next memory address, which was where authenticated was stored. [06:31.350 --> 06:35.830] The hex value for these X's is non-zero. [06:36.090 --> 06:36.850] Let me switch back. [06:38.310 --> 06:41.850] The hex value for those X's are non-zero. [06:42.490 --> 06:47.970] And so if authenticated is non-zero, you just authenticated. [06:57.080 --> 07:04.760] So the first way to prevent against this buffer overflow is to use the strn functions. [07:06.220 --> 07:08.980] That's strn cat, strn copy. [07:09.640 --> 07:11.920] Those are the function definitions right there. [07:13.280 --> 07:17.860] It takes three arguments, destination, source, and a size. [07:19.120 --> 07:24.320] I maintain that these functions have some quirks to them, because they're a little non-intuitive. [07:24.820 --> 07:27.840] If you use these all the time, you can use them safely. [07:28.400 --> 07:32.640] But there's little things here and there that make it difficult. [07:32.640 --> 07:39.400] So for example, your third variable n refers to how many characters to copy from source. [07:39.900 --> 07:42.100] It has nothing to do with dust. [07:42.380 --> 07:50.160] So if you're trying to protect overflow and dust, the destination, that third argument, there's no correlation. [07:50.880 --> 07:52.400] So it's a little non-intuitive. [07:52.680 --> 07:56.240] It is possible to use correctly, but I maintain it as a little non-intuitive. [08:01.960 --> 08:03.020] Here's an example. [08:05.060 --> 08:09.760] Two character arrays, eight bytes each. [08:11.520 --> 08:16.400] Copy a string yoDude, which is seven bytes long, into BUF. [08:17.880 --> 08:22.400] It'll be null terminated, which means it occupies the entire buffer. [08:23.460 --> 08:29.400] The next copy is copying AV1 into BUF2. [08:32.820 --> 08:35.500] And on the right is an illustration of what happens when we run it. [08:35.660 --> 08:38.560] We run it with seven bytes of input. [08:39.020 --> 08:42.440] We print them both out, and that's exactly what you expect. [08:44.900 --> 08:50.080] Input more than seven, and look at what happens at BUF2. [08:51.040 --> 09:00.760] We overwrote the null terminator, and BUF2 became coalesced with BUF1. [09:01.780 --> 09:03.240] This is a problem. [09:14.690 --> 09:15.790] Hold on. [09:17.210 --> 09:17.990] Yeah. [09:19.390 --> 09:22.870] A safer replacement would be the strl functions. [09:23.650 --> 09:26.650] They were introduced in OpenBSD 2.4. [09:26.950 --> 09:37.370] They have similar definitions as the strncat strlcopy functions, but they're safer in that that they protect DST. [09:38.490 --> 09:43.510] They guarantee that no more than size bytes are written into DST. [09:44.130 --> 09:48.890] And furthermore, it guarantees that a null terminator is written into DST. [09:49.170 --> 09:53.450] As we saw before, it is possible to overwrite the null terminator. [09:55.270 --> 09:57.030] So this protects against that. [09:57.930 --> 09:59.650] This is safer to use. [09:59.790 --> 10:00.430] It's more intuitive. [10:02.930 --> 10:04.810] Unfortunately, it's not portable. [10:04.810 --> 10:08.390] I believe OpenBSD is the only system that it exists upon. [10:08.570 --> 10:08.930] I saw. [10:09.350 --> 10:09.630] Shake, no. [10:09.750 --> 10:10.150] What's that? [10:10.270 --> 10:11.570] I think the other BSDs. [10:11.570 --> 10:12.770] The other BSDs include that? [10:12.890 --> 10:13.610] Okay, that makes sense. [10:13.730 --> 10:14.790] I don't believe that's on Linux. [10:17.770 --> 10:25.810] Yeah, so the moral of this story is if you're trying to write code for those platforms, emulate it. [10:26.110 --> 10:27.350] It is easy to emulate. [10:27.590 --> 10:28.850] I've emulated it myself. [10:29.290 --> 10:31.310] If you want my code, I'll give it to you. [10:31.490 --> 10:32.090] Just email me. [10:39.370 --> 10:40.770] Next, strings. [10:41.190 --> 10:45.370] Strings are aware of their size, so they automatically resize themselves as necessary. [10:46.030 --> 10:51.650] Versus character arrays, which are just ranges of memory addresses that don't grow. [10:51.810 --> 10:52.210] They're set. [10:53.470 --> 10:57.390] Strings are aware of their size, so they resize themselves. [10:58.710 --> 11:01.130] Any Java programmers in here? [11:01.770 --> 11:03.570] Do we have any Java programmers? [11:05.010 --> 11:06.770] What, like 10 people? [11:07.810 --> 11:08.310] Okay. [11:09.070 --> 11:09.530] Yeah. [11:09.870 --> 11:12.170] You guys know how easy it is to manipulate strings. [11:12.190 --> 11:13.610] It is very, very simple. [11:14.370 --> 11:15.570] Versus people... [11:15.570 --> 11:20.690] Have you then switched back to C and try to manipulate strings then? [11:20.690 --> 11:22.010] It's pain. [11:22.490 --> 11:24.930] That's all I can describe it as. [11:25.830 --> 11:29.210] The interface there is very nice and very polished. [11:29.750 --> 11:33.450] From the functional standpoint, strings are so much easier to use. [11:33.650 --> 11:38.890] And from the security standpoint, it's better because you don't have to worry about buffer overflows. [11:39.390 --> 11:41.030] The strings take care of themselves. [11:41.030 --> 11:47.610] You do have to worry about buffer overflows in the string library, but that is a set location of code. [11:47.790 --> 11:52.430] Small, it's centralized, and it can be audited multiple times. [11:53.750 --> 11:56.930] And surprisingly, in the C language, you can use strings. [11:57.390 --> 11:58.610] How many people actually knew that? [11:59.810 --> 12:00.410] Nobody. [12:00.810 --> 12:01.450] You can. [12:06.240 --> 12:10.940] One popular implementation in C is from the G library. [12:12.720 --> 12:14.400] Here's an example of the interface. [12:17.460 --> 12:26.240] You have G string new, which takes a, you know, set initial value, returns a G string. [12:30.720 --> 12:32.300] Okay, a couple people got that. [12:34.030 --> 12:38.850] Yeah, so when you want to keep appending to this string, you have G string append printf, which just keeps... [12:39.480 --> 12:45.820] You use C formatters, and you can just dump all kinds of data in there, and it grows, and you don't need to worry about it. [12:47.060 --> 12:48.320] So, it is possible. [12:48.580 --> 12:50.400] Take a look at the struct on the left. [12:52.020 --> 12:56.240] You have str, which is a character array, a dynamic character array. [12:57.240 --> 13:00.700] Len, which contains the current length. [13:01.840 --> 13:06.880] Allocated len, which is how large str is currently allocated. [13:06.880 --> 13:16.460] So, when it gets too big, these functions on the right will reallocate str as necessary and do copying if needed and so on. [13:21.170 --> 13:24.610] Another technique, proactive technique, wasting space. [13:26.090 --> 13:26.970] The problem. [13:27.210 --> 13:32.170] Common off-by-one errors and array manipulations can overwrite past the end of a buffer. [13:34.690 --> 13:41.590] To guard against that, you can declare your buffers slightly larger than you need. [13:42.830 --> 13:59.490] If you declare them, say, one word size or two word sizes, which are four bytes each, four bytes per word on the 32-bit architectures, then if you have an off-by-one error or off-by-two, which are much more rare but still happen, you are safe. [13:59.750 --> 14:05.090] Off-by-one, overflows are exploitable sometimes, and they are a big deal. [14:09.270 --> 14:13.210] Some compilers actually do this automatically. [14:13.490 --> 14:19.470] From GCC 3.0 and further, does this automatically. [14:19.470 --> 14:29.070] You'll notice if you disassemble any programs that you declare a buffer 16 bytes long, and magically it's like 24 bytes when you disassemble. [14:29.370 --> 14:30.790] It's doing that on purpose. [14:31.850 --> 14:33.490] Not all compilers do this. [14:33.650 --> 14:36.530] Does anybody know if the Microsoft compiler does this? [14:37.290 --> 14:38.170] I don't know. [14:38.270 --> 14:39.410] I'm not a Windows programmer. [14:40.250 --> 14:41.330] Primarily nobody knows. [14:41.910 --> 14:43.310] I'm not sure if it does that. [14:43.330 --> 14:44.130] It's not standard. [14:45.030 --> 14:52.730] So if you want to do this on multiple platforms, you have to do this yourself. [14:53.470 --> 14:54.410] It's a pain. [14:54.670 --> 14:55.830] I'm not going to lie. [14:56.190 --> 14:59.010] It takes a certain amount of obsession to do this. [14:59.790 --> 15:00.730] And patience. [15:04.340 --> 15:06.760] Next, variable reordering. [15:07.680 --> 15:13.000] The stack variables can be reordered so the impact of buffer overflows are minimized. [15:14.160 --> 15:22.280] Like I showed before, the compiler will arrange variables in a set way backwards in memory. [15:23.020 --> 15:25.680] The later variables are put in low memory. [15:26.160 --> 15:30.440] So certain variable types are overflowed more than others. [15:30.740 --> 15:31.380] Character arrays. [15:32.680 --> 15:41.640] So if you put those in later memory, an off by one error is not going to overflow something more important like an integer or something like that. [15:41.880 --> 15:48.840] You can still overflow into the next memory address, but the impact is minimized. [15:48.840 --> 15:49.460] It's not a guarantee. [15:49.660 --> 15:52.720] It's not a full solution. [15:54.480 --> 15:59.860] But the ProPolice stack in OpenBSD implements this. [16:00.120 --> 16:03.820] Just as an example of this in action. [16:04.180 --> 16:12.520] You can implement this yourself with a program, a preprocessor program, or just use ProPolice. [16:15.520 --> 16:17.580] Also, this is tedious to do by hand. [16:26.170 --> 16:27.850] Next, pointer nullification. [16:28.270 --> 16:34.530] The problem here, freeing a dynamic memory allocation twice can corrupt the heap structure in a controllable way. [16:36.130 --> 16:43.510] This happened four years ago, I remember, in the Z library, which is a compression library used by a lot of projects. [16:45.190 --> 16:47.070] It's embedded sometimes statically. [16:47.450 --> 16:55.170] There was a vulnerability, a double free vulnerability, where free was called twice on the same pointer, which turned out to be exploitable. [16:55.850 --> 16:58.430] Although I don't think details were ever released. [17:02.830 --> 17:13.510] From this, I learned, if you nullify pointers immediately after you free them, this protects you from this class of vulnerability. [17:14.270 --> 17:19.090] And the reason for that is that NCC defines free of a null pointer as having no effect. [17:19.090 --> 17:33.050] So if you use this macro, my free, which frees your pointer and then immediately sets it to null, calling my free x on the same pointer twice in a row has no effect. [17:33.250 --> 17:37.430] There is no security vulnerability that arises because of this. [17:39.750 --> 17:49.350] Once upon a time, I thought that using this macro would make your program invincible to double free vulnerabilities. [17:50.650 --> 17:53.650] Can anybody point out why that is not true? [18:01.400 --> 18:02.380] In the front. [18:02.580 --> 18:03.560] The parentheses around the second x? [18:04.900 --> 18:06.920] Uh, no. [18:07.880 --> 18:09.820] If my free is declared as a string? [18:11.760 --> 18:12.440] What's that? [18:12.620 --> 18:14.700] If my free is declared as a string? [18:16.420 --> 18:16.920] No. [18:17.920 --> 18:19.420] I'm not sure what you mean by that. [18:19.960 --> 18:22.080] If it's declared as a string, you said it's a null. [18:23.000 --> 18:25.860] And it then somehow becomes a string and you will out. [18:27.300 --> 18:27.800] Oh. [18:29.440 --> 18:30.300] Pointer copying. [18:30.660 --> 18:35.800] If a program copies pointers all over the place, you might just set a local pointer null, but not... [18:35.800 --> 18:40.440] the owner of the variable still has a valid memory address. [18:41.980 --> 18:43.620] That one caught me by surprise. [18:47.700 --> 18:48.340] Comments. [18:48.580 --> 18:51.140] These can protect against buffer overflows or logic errors. [18:51.840 --> 18:57.200] A good software engineer knows that the code that they write will be maintained by multiple people. [18:57.660 --> 19:04.680] These people have differing skill sets, cognitive abilities, mental state, which includes motivation, mood, and alertness. [19:04.680 --> 19:09.520] Good comments will lower the chances a maintainer introduces security vulnerabilities. [19:09.820 --> 19:14.580] There is a heavy psychology component in team programming. [19:15.370 --> 19:19.720] You need to make it as simple as possible for someone to maintain. [19:19.720 --> 19:32.900] This is hard to do, to get into somebody's head and try to understand how will a beginner see this code and how will they misunderstand something. [19:33.480 --> 19:40.200] And then try to write code comments that demystify your original design techniques, your design methodology. [19:40.200 --> 19:46.560] That's hard to do, but I believe if you try hard enough, you will get this right. [19:53.210 --> 19:54.930] Next, simple code. [19:56.110 --> 19:59.070] Can protect against buffer overflows and logic errors. [20:00.610 --> 20:06.850] Here's the winner of the 1985 International Obfuscated C Code Contest. [20:08.650 --> 20:09.990] That's the winner. [20:10.210 --> 20:12.590] I don't know what that single line does. [20:13.110 --> 20:15.310] There's a lot of pointer dereferencing. [20:20.060 --> 20:22.300] No, there's not too many... [20:23.160 --> 20:25.020] There's not too many pointers... [20:25.020 --> 20:27.220] Well, yeah, there's some pointer arithmetic, I guess you can say. [20:27.640 --> 20:31.540] The bottom line is don't do pointer arithmetic, because that gets you in a lot of trouble. [20:31.940 --> 20:32.920] You don't need to do that. [20:33.080 --> 20:35.780] Break it up into a couple lines with some good comments. [20:35.940 --> 20:36.860] That's easier to maintain. [20:39.900 --> 20:41.820] There's... I mean, some people are really... [20:42.520 --> 20:44.740] really like to write complex code. [20:44.840 --> 20:45.920] It makes them feel tough. [20:47.600 --> 20:48.900] You have to break out of that. [20:49.260 --> 20:51.160] It doesn't help the person maintaining it. [20:53.400 --> 20:54.560] What does that do, actually? [20:55.060 --> 20:55.580] What's that? [20:55.580 --> 20:56.280] What does that do? [20:56.500 --> 20:58.000] The question is, what does that do? [21:00.140 --> 21:01.220] Writing simple code? [21:01.480 --> 21:02.280] No, what is that? [21:02.880 --> 21:03.780] Oh, that? [21:03.960 --> 21:04.540] Oh, I don't know. [21:04.720 --> 21:07.760] I just went to the web page and grabbed something hideous. [21:13.140 --> 21:14.020] Variable initializations. [21:15.380 --> 21:25.680] If you initialize variables right after they're declaring them, this protects you because on the stack, your variables are uninitialized. [21:25.820 --> 21:26.720] If you... [21:27.480 --> 21:30.580] In the sense that they... you don't know what they contain. [21:30.900 --> 21:39.880] They contain values that exist from previous function calls, which could be controlled by an attacker. [21:40.560 --> 21:46.040] So, if you use an uninitialized variable, that could be used to... [21:46.040 --> 21:50.960] That could lead to your program being compromised. [21:51.420 --> 21:54.880] So, always initializing your variables is... [21:56.360 --> 21:59.800] gives you some security benefit, but also a very bit... [21:59.800 --> 22:01.980] more of a... [22:02.540 --> 22:03.800] usability and... [22:05.900 --> 22:07.120] What am I looking for? [22:10.400 --> 22:11.480] It helps... [22:11.480 --> 22:15.200] It's faster to program like that because, I mean... [22:15.200 --> 22:16.780] your programs will fail fast. [22:16.940 --> 22:22.240] If you use an uninitialized variable, it'll fail every single time... [22:22.240 --> 22:22.560] consistently. [22:29.710 --> 22:30.990] Default failure... [22:30.990 --> 22:32.670] can prevent logic errors. [22:32.670 --> 22:35.050] Let's say you are switching between states. [22:35.670 --> 22:37.990] You're maintaining some kind of state information. [22:38.610 --> 22:40.850] On the left, we're checking states... [22:41.510 --> 22:42.670] between one, two, and three. [22:43.150 --> 22:44.470] Notice that if... [22:44.470 --> 22:46.890] it's not state one and state two... [22:46.890 --> 22:48.390] we're just assuming state three. [22:49.930 --> 22:52.970] A more proactive approach would be on the right... [22:52.970 --> 22:54.690] you check your three states... [22:54.690 --> 22:56.370] and default to an error. [22:56.750 --> 22:58.070] This is kind of... [22:58.070 --> 22:59.810] this is similar to a... whitelist. [23:01.410 --> 23:02.710] This is whitelisting. [23:06.010 --> 23:07.910] If you add states... [23:07.910 --> 23:09.910] your code on the left will break... [23:10.550 --> 23:12.970] because you're assuming state three when... [23:12.970 --> 23:14.770] you created a state four. [23:16.370 --> 23:17.290] Or if... [23:17.290 --> 23:19.310] the state variable itself becomes corrupt... [23:19.310 --> 23:20.330] that also leads to errors. [23:24.100 --> 23:25.590] And those are my references. [23:26.630 --> 23:27.640] I'll take any questions... [23:28.900 --> 23:29.540] if any. [23:31.610 --> 23:32.050] Yep. [23:33.040 --> 23:34.040] Can I go over here? [23:34.140 --> 23:34.380] Yes. [23:38.230 --> 23:41.150] So what kind of vulnerabilities are you talking about? [23:41.210 --> 23:43.890] Are you just talking about someone just running a C program? [23:43.890 --> 23:44.490] or... [23:44.490 --> 23:46.070] are you talking about like... [23:46.070 --> 23:48.050] someone using this sort of website? [23:48.610 --> 23:49.250] Or... [23:49.250 --> 23:50.870] having C being the... [23:50.870 --> 23:54.210] having C being the... [23:54.890 --> 23:55.650] the hand... [23:55.650 --> 23:56.690] how it handles it? [23:56.930 --> 23:58.190] Or what are you talking about? [23:58.370 --> 23:58.890] Any... [23:58.890 --> 24:00.150] any programs... [24:00.150 --> 24:01.830] written in direct memory languages. [24:02.370 --> 24:02.650] So... [24:02.650 --> 24:03.210] assembly... [24:03.210 --> 24:05.030] so you C++... [24:05.030 --> 24:05.610] that... [24:05.610 --> 24:06.570] Where you do like... [24:06.570 --> 24:07.510] running root as... [24:07.510 --> 24:08.130] like... [24:08.550 --> 24:09.070] or something? [24:10.710 --> 24:11.270] Um... [24:11.270 --> 24:12.730] anything where... [24:12.730 --> 24:12.910] you're... [24:12.910 --> 24:15.090] you're handling input from an untrusted user. [24:16.030 --> 24:16.310] Oh... [24:16.310 --> 24:16.890] you have like a database? [24:16.890 --> 24:18.510] Or a user of a different privilege. [24:19.110 --> 24:19.310] Oh... [24:19.310 --> 24:20.230] so you have like a database? [24:21.910 --> 24:23.330] That would be applicable, yes. [24:23.990 --> 24:24.190] Oh. [24:25.430 --> 24:25.990] And... [24:25.990 --> 24:27.450] so what other kinds of... [24:27.450 --> 24:30.470] bad programming can get you in trouble besides like... [24:30.470 --> 24:31.210] the obvious... [24:31.210 --> 24:31.990] buffer overflows? [24:33.770 --> 24:35.010] I'm sorry, could you rephrase? [24:35.050 --> 24:35.610] What are pro... [24:35.610 --> 24:36.230] what kind of... [24:36.230 --> 24:39.010] kinds of bad programming things that you can do besides... [24:39.010 --> 24:40.890] up buffer overflows that will get you in trouble? [24:42.890 --> 24:43.370] Uh... [24:43.370 --> 24:44.110] that's a big question. [24:44.310 --> 24:44.750] There's... [24:44.750 --> 24:47.630] many classes of code vulnerabilities... [24:47.630 --> 24:48.010] uh... [24:48.010 --> 24:49.830] buffer overflows... [24:49.830 --> 24:50.170] um... [24:50.170 --> 24:51.750] double freeze like I talked about. [24:52.850 --> 24:54.190] Is there a way to test like... [24:54.190 --> 24:56.650] if someone's gonna run some kind of debugger on you... [24:56.650 --> 24:57.430] on your program... [24:58.710 --> 24:58.810] and... [24:58.810 --> 25:00.350] try to find vulnerabilities in it? [25:00.350 --> 25:01.110] Uh... [25:01.110 --> 25:01.770] I'm sure there are. [25:01.970 --> 25:02.550] That's... [25:02.550 --> 25:04.150] beyond the scope of this presentation. [25:04.430 --> 25:04.510] Oh. [25:05.210 --> 25:05.590] Okay. [25:06.270 --> 25:06.710] That's all. [25:10.430 --> 25:11.650] Any last questions? [25:15.150 --> 25:15.930] All right. [25:16.370 --> 25:17.550] Well, thank you. [25:17.550 --> 25:17.570] oberorn Nowil tutor, I do. [25:17.570 --> 25:17.590] Thank you. [25:18.790 --> 25:19.410] I also... [25:22.460 --> 25:23.560] I also have hands...