1 00:00:00,000 --> 00:00:02,130 - Well without further ado. 2 00:00:02,130 --> 00:00:03,180 Let's welcome, Jonathan. 3 00:00:03,180 --> 00:00:04,830 Who's a first time speaker, 4 00:00:04,830 --> 00:00:05,663 Jonathan 5 00:00:06,721 --> 00:00:10,804 (audience clapping and cheering) 6 00:00:13,245 --> 00:00:15,240 (laughing) 7 00:00:15,240 --> 00:00:16,240 Thank you everybody. 8 00:00:18,512 --> 00:00:20,820 So the talk that I'm gonna give here in front of you all is 9 00:00:20,820 --> 00:00:22,170 'Scaling the Security Researcher 10 00:00:22,170 --> 00:00:24,330 to Eliminate OSS Vulnerabilities 11 00:00:24,330 --> 00:00:25,353 Once and For All' 12 00:00:27,345 --> 00:00:28,178 So yeah, let's get started. 13 00:00:28,178 --> 00:00:29,986 Thank you all for coming 14 00:00:29,986 --> 00:00:31,050 and thank you for being here this early. 15 00:00:31,050 --> 00:00:32,490 I know that I had a hard time waking up. 16 00:00:32,490 --> 00:00:34,576 I can imagine some of you did as well. 17 00:00:34,576 --> 00:00:36,270 (laughing) 18 00:00:36,270 --> 00:00:37,103 Okay. 19 00:00:37,992 --> 00:00:39,300 So my name is Jonathan Leitschuh 20 00:00:39,300 --> 00:00:42,648 I'm a software engineer and software security researcher. 21 00:00:42,648 --> 00:00:45,180 I'm the first ever Dan Kaminsky Fellow @ HUMAN Security; 22 00:00:45,180 --> 00:00:46,200 I'm a GitHub star, 23 00:00:46,200 --> 00:00:48,519 a GitHub security ambassador. 24 00:00:48,519 --> 00:00:51,693 And you can find me @Jleitschuh on Twitter. 25 00:00:52,779 --> 00:00:54,847 You can also find me at the same handle on GitHub. 26 00:00:56,580 --> 00:00:57,413 Yes. 27 00:01:05,850 --> 00:01:06,683 Oh. 28 00:01:08,379 --> 00:01:09,212 - Everybody can see your second slide. 29 00:01:09,212 --> 00:01:10,083 - Oh, interesting. 30 00:01:11,100 --> 00:01:12,213 One moment please. 31 00:01:16,080 --> 00:01:16,923 - Go to logo. 32 00:01:18,180 --> 00:01:19,083 Go to logo. 33 00:01:31,263 --> 00:01:32,196 I apologize. 34 00:01:32,196 --> 00:01:33,920 - It's only fun if there's technical difficulties. 35 00:01:33,920 --> 00:01:36,170 (laughing) 36 00:01:37,040 --> 00:01:40,457 - [Audience] (inaudible) 37 00:01:43,290 --> 00:01:45,020 - Oh, if you just pop it in... 38 00:01:47,066 --> 00:01:47,998 - What? 39 00:01:47,998 --> 00:01:49,618 No, I gotta make sure that 40 00:01:49,618 --> 00:01:50,451 The video's extended, yeah 41 00:01:50,451 --> 00:01:53,180 The video looks right, yeah 42 00:01:53,180 --> 00:01:55,442 - It is coming up on the screen 43 00:01:55,442 --> 00:01:56,520 - Is coming out. 44 00:01:56,520 --> 00:01:57,599 The same thing you're seeing here 45 00:01:57,599 --> 00:01:58,470 is the same thing they're 46 00:01:58,470 --> 00:01:59,303 seeing up there, yeah. 47 00:02:00,629 --> 00:02:01,462 Sorry, and that dude walked out. 48 00:02:01,462 --> 00:02:02,900 I tried to tell him when he was up here. 49 00:02:05,942 --> 00:02:06,930 - Okay, it's extending 50 00:02:08,070 --> 00:02:09,570 Maybe its because we changed it mid stream 51 00:02:11,335 --> 00:02:13,179 Maybe if you try reloading, it it'll work. 52 00:02:13,179 --> 00:02:14,377 - Okay. 53 00:02:14,377 --> 00:02:16,127 - It's the one there. 54 00:02:19,326 --> 00:02:20,159 - No 55 00:02:20,159 --> 00:02:21,158 - Try it here, do this. 56 00:02:21,158 --> 00:02:21,991 - Hold on. hold on 57 00:02:21,991 --> 00:02:23,242 Just go back. 58 00:02:23,242 --> 00:02:24,075 - Yeah. 59 00:02:25,350 --> 00:02:26,950 Can you take us back to screen ? 60 00:02:29,490 --> 00:02:30,323 SDI 61 00:02:35,580 --> 00:02:36,680 No, no, no, I got you. 62 00:02:38,483 --> 00:02:40,533 - [Man Wearing mask] I'm just (inaudible) 63 00:02:42,775 --> 00:02:46,467 (audience clapping and cheering) 64 00:02:46,467 --> 00:02:47,922 Awesome. 65 00:02:47,922 --> 00:02:50,078 (laughing) 66 00:02:50,078 --> 00:02:50,911 All right. 67 00:02:50,911 --> 00:02:52,346 Let's take this from the top. 68 00:02:52,346 --> 00:02:53,179 (laughing) 69 00:02:53,179 --> 00:02:54,012 Alright. 70 00:02:54,012 --> 00:02:54,845 So yes, 71 00:02:54,845 --> 00:02:56,031 welcome to 72 00:02:56,031 --> 00:02:57,222 'Scaling the Security Researcher 73 00:02:57,222 --> 00:02:58,055 to Eliminate OSS Vulnerabilities 74 00:02:58,055 --> 00:02:59,007 Once and For All.' 75 00:03:00,180 --> 00:03:01,740 My name's Jonathan Leitschuh 76 00:03:01,740 --> 00:03:04,473 I'm not gonna run through all this again, but anyways. 77 00:03:05,490 --> 00:03:08,070 Yeah, you can find me on Twitter @JLeitschuh 78 00:03:08,070 --> 00:03:09,183 My DMs are open. 79 00:03:11,333 --> 00:03:13,470 Also, my co-presenter was not able to make it at D3FCON, 80 00:03:13,470 --> 00:03:14,520 but his name is Patrick Way 81 00:03:14,520 --> 00:03:15,640 and he's from Moderne 82 00:03:17,901 --> 00:03:19,103 and you can also reach out to him on Twitter. 83 00:03:20,061 --> 00:03:21,143 So a little bit of a disclaimer. 84 00:03:21,990 --> 00:03:23,943 First off, I'm sponsored by GitHub. 85 00:03:24,840 --> 00:03:25,770 I have to say that legally 86 00:03:25,770 --> 00:03:28,023 and also the talk, 87 00:03:28,865 --> 00:03:29,760 this will discuss a Saas offering 88 00:03:29,760 --> 00:03:32,073 that is sold to customers or to companies, 89 00:03:33,158 --> 00:03:36,030 but all the technologies and tools that are discussed here 90 00:03:36,030 --> 00:03:37,713 are available for free, for OSS. 91 00:03:39,221 --> 00:03:40,770 And you can use them as security researchers to find these 92 00:03:40,770 --> 00:03:42,960 tools without paying anything so, 93 00:03:42,960 --> 00:03:44,560 and fix vulnerabilities as well. 94 00:03:45,570 --> 00:03:49,320 So this talk and the work that I've been doing, 95 00:03:49,320 --> 00:03:52,590 sponsored by the new Dan Kaminsky fellowship. 96 00:03:52,590 --> 00:03:54,690 For those who don't know, 97 00:03:54,690 --> 00:03:57,400 Dan was a security researcher 98 00:03:58,481 --> 00:04:00,120 who was known for a famous vulnerability in DNS 99 00:04:00,120 --> 00:04:01,323 back in 2008. 100 00:04:03,193 --> 00:04:05,640 I sadly never got the opportunity to meet Dan. 101 00:04:05,640 --> 00:04:08,230 He was known as a very, very kind person 102 00:04:09,401 --> 00:04:10,410 and people in this community.... 103 00:04:10,410 --> 00:04:12,310 He was a cornerstone of this community 104 00:04:14,249 --> 00:04:16,260 and the Dan Kaminsky fellowship was created 105 00:04:16,260 --> 00:04:19,560 to celebrate Dan's legacy and memory 106 00:04:19,560 --> 00:04:21,060 by funding OSS work 107 00:04:21,060 --> 00:04:24,210 that makes the world a better and more secure place. 108 00:04:24,210 --> 00:04:27,600 HUMAN is currently accepting the 2020 applications 109 00:04:27,600 --> 00:04:28,860 for the next Dan Kaminsky fellow. 110 00:04:28,860 --> 00:04:31,140 So if you have a project 111 00:04:31,140 --> 00:04:34,364 that helps improve the security of the internet. 112 00:04:34,364 --> 00:04:36,780 And you're looking for a year long way to finance that 113 00:04:36,780 --> 00:04:38,590 as a project that you do full time 114 00:04:39,540 --> 00:04:41,790 consider applying to Dan Kamimsky fellowship. 115 00:04:45,627 --> 00:04:46,460 So my research and this work 116 00:04:46,460 --> 00:04:47,293 started with a simple vulnerability. 117 00:04:48,780 --> 00:04:51,510 This was in my company's build.gradle file. 118 00:04:51,510 --> 00:04:53,760 And I was curious how this ended up there. 119 00:04:53,760 --> 00:04:56,070 It was the use of HTTP to resolve dependencies. 120 00:04:56,070 --> 00:04:58,182 And the reason this ended up there 121 00:04:58,182 --> 00:04:59,015 was cause I'd copied and pasted it 122 00:04:59,015 --> 00:05:00,990 from an OSS project. 123 00:05:00,990 --> 00:05:03,420 And the reason that using HTTP instead of HTTPS, 124 00:05:03,420 --> 00:05:06,894 to resolve your dependencies in a build tool 125 00:05:06,894 --> 00:05:08,662 like Gradle or Maven 126 00:05:08,662 --> 00:05:11,020 is because you can have your build tool 127 00:05:12,430 --> 00:05:13,270 or the JARs that you're downloading 128 00:05:13,270 --> 00:05:15,270 compromised in flight, 129 00:05:15,270 --> 00:05:16,500 as they're getting downloaded 130 00:05:16,500 --> 00:05:18,400 with an attacker in the middle attack. 131 00:05:21,474 --> 00:05:23,700 And so this vulnerability wasn't just in Gradle builds, 132 00:05:23,700 --> 00:05:25,113 I found that it was also, 133 00:05:26,214 --> 00:05:27,653 this is an example of it existing in Maven builds. 134 00:05:28,710 --> 00:05:30,630 This is where the JAR that you're downloading 135 00:05:30,630 --> 00:05:33,120 gets downloaded and used 136 00:05:33,120 --> 00:05:34,590 in the compiler and test dependencies, 137 00:05:34,590 --> 00:05:35,910 which means it's actually executed 138 00:05:35,910 --> 00:05:37,383 on the developers machine. 139 00:05:38,318 --> 00:05:40,390 And this is where it appears 140 00:05:40,390 --> 00:05:42,592 in the upload of your artifact 141 00:05:42,592 --> 00:05:43,425 as you're releasing the artifact, 142 00:05:43,425 --> 00:05:45,690 which usually includes credentials 143 00:05:45,690 --> 00:05:46,523 as the upload. 144 00:05:46,523 --> 00:05:47,927 So of course, 145 00:05:47,927 --> 00:05:48,760 you're leaking the credentials 146 00:05:48,760 --> 00:05:49,593 to upload artifacts as part 147 00:05:49,593 --> 00:05:50,640 of your build process 148 00:05:50,640 --> 00:05:51,693 over Plane text. 149 00:05:52,897 --> 00:05:54,510 And this vulnerability was everywhere. 150 00:05:54,510 --> 00:05:56,040 It impacted the organizations 151 00:05:56,040 --> 00:05:57,720 like spring, Red Hat, 152 00:05:57,720 --> 00:06:00,173 Apache, Kotlin, JetBrains, 153 00:06:00,173 --> 00:06:01,470 Gradle, Jenkins, 154 00:06:01,470 --> 00:06:04,020 Groovy, Elastic, Eclipse. 155 00:06:04,020 --> 00:06:04,853 And on top of that, 156 00:06:04,853 --> 00:06:08,130 it impacted Oracle, the NSA, LinkedIn, 157 00:06:08,130 --> 00:06:08,963 and Stripe, 158 00:06:08,963 --> 00:06:10,920 all of the OSS projects 159 00:06:10,920 --> 00:06:12,540 from all of these different organizations 160 00:06:12,540 --> 00:06:14,340 were impacted by this vulnerability. 161 00:06:15,330 --> 00:06:17,520 So I reached out to Maven Sonatype 162 00:06:17,520 --> 00:06:19,980 Maven Sonartype is the equivalent of PIP for the 163 00:06:19,980 --> 00:06:21,480 Python ecosystem, 164 00:06:21,480 --> 00:06:23,160 npm for the Java ecosystem. 165 00:06:23,160 --> 00:06:24,150 And they said that 166 00:06:24,150 --> 00:06:26,940 when they looked at their traffic in 2019 167 00:06:26,940 --> 00:06:30,300 25% of their traffic was still using HTTP to 168 00:06:30,300 --> 00:06:31,563 download dependencies. 169 00:06:32,940 --> 00:06:34,800 So how do we fix this? 170 00:06:34,800 --> 00:06:36,900 So on January 15th, 2020, 171 00:06:36,900 --> 00:06:38,310 I pushed forward an initiative 172 00:06:38,310 --> 00:06:40,200 that decommissioned the support for HTTP 173 00:06:40,200 --> 00:06:41,730 in favor of HTTPS only 174 00:06:41,730 --> 00:06:44,530 across the major artifact servers and the Java ecosystem 175 00:06:46,568 --> 00:06:47,574 and reached back 176 00:06:47,574 --> 00:06:50,880 out to Maven Sonatype in January, 2020. 177 00:06:50,880 --> 00:06:51,713 And they said, 178 00:06:51,713 --> 00:06:53,370 even after the blog posts, 179 00:06:53,370 --> 00:06:55,220 the discussion of this vulnerability, 180 00:06:56,321 --> 00:06:59,100 there were still about 20% of their traffic 181 00:06:59,100 --> 00:06:59,933 that they were seeing 182 00:06:59,933 --> 00:07:02,013 using HTTP instead of HTTPS. 183 00:07:05,350 --> 00:07:07,920 So you can imagine what might have happened 184 00:07:07,920 --> 00:07:09,990 on January 15th, 2020 185 00:07:12,240 --> 00:07:14,142 broken software everywhere. 186 00:07:14,142 --> 00:07:14,975 (laughing) 187 00:07:14,975 --> 00:07:16,530 There's a lot of stack overflow saying 188 00:07:16,530 --> 00:07:18,327 what happened to my build ? 189 00:07:20,827 --> 00:07:22,740 But we stopped the bleeding. 190 00:07:22,740 --> 00:07:25,470 However, what about the other repositories? 191 00:07:25,470 --> 00:07:28,080 These are only the most commonly used repositories 192 00:07:28,080 --> 00:07:29,010 in the Java ecosystem, 193 00:07:29,010 --> 00:07:30,580 Maven Central, Jcenter, Spring 194 00:07:31,463 --> 00:07:32,296 and the Gradle plugin portal. 195 00:07:32,296 --> 00:07:34,413 Other companies host artifacts, 196 00:07:36,370 --> 00:07:38,430 and you see them in the builds of companies 197 00:07:38,430 --> 00:07:41,220 or builds across the ecosystem. 198 00:07:41,220 --> 00:07:44,610 Unlike NPM or PIP, 199 00:07:44,610 --> 00:07:47,100 you can declare multiple repositories to resolve your 200 00:07:47,100 --> 00:07:48,978 dependencies from. 201 00:07:48,978 --> 00:07:50,070 And so you'll see that there's some builds 202 00:07:50,070 --> 00:07:52,950 that rely upon 5, 6, 7, 8 repositories 203 00:07:52,950 --> 00:07:55,890 to resolve their dependencies across the job ecosystem. 204 00:07:55,890 --> 00:07:57,600 So how do we fix the rest? 205 00:07:57,600 --> 00:07:58,433 And I said, 206 00:08:00,375 --> 00:08:01,470 well, let's go to the root of the problem. 207 00:08:01,470 --> 00:08:04,050 And let's just generate pull requests. 208 00:08:04,050 --> 00:08:05,670 Let's fix it this way. 209 00:08:05,670 --> 00:08:07,620 So how did I do this? 210 00:08:07,620 --> 00:08:08,610 The first thing that I needed to do 211 00:08:08,610 --> 00:08:11,510 is I needed to identify the projects that were vulnerable. 212 00:08:12,600 --> 00:08:13,920 You can know that the vulnerability exists, 213 00:08:13,920 --> 00:08:16,620 but how do you get a list of projects to go fix it in? 214 00:08:17,462 --> 00:08:19,140 And so I use CodeQL, 215 00:08:19,140 --> 00:08:20,190 this is the query. 216 00:08:20,190 --> 00:08:22,230 I wrote this query to find this vulnerability 217 00:08:22,230 --> 00:08:23,820 in Maven POM files. 218 00:08:23,820 --> 00:08:26,730 It's very simple, that's it, right? 219 00:08:26,730 --> 00:08:27,563 It's very short. 220 00:08:28,486 --> 00:08:30,236 And the reason that I use CodeQL is 221 00:08:31,082 --> 00:08:32,250 CodeQL scans hundreds of thousands 222 00:08:32,250 --> 00:08:33,943 of OSS projects on every command. 223 00:08:33,943 --> 00:08:35,235 And you can write it 224 00:08:35,235 --> 00:08:38,026 as you're building the software, as it's building, 225 00:08:38,026 --> 00:08:41,100 they extract the ASTs 226 00:08:41,100 --> 00:08:43,530 and they build a database of the code 227 00:08:43,530 --> 00:08:45,363 that you can write queries against. 228 00:08:47,850 --> 00:08:51,270 And GitHub also has a bug bounty program called 229 00:08:51,270 --> 00:08:52,860 the GitHub security lab bug bounty program. 230 00:08:52,860 --> 00:08:55,682 There's actually two bug bounty programs under it. 231 00:08:55,682 --> 00:08:58,530 And for this very simple query that I wrote, 232 00:08:58,530 --> 00:09:00,693 GitHub bountied me $2,300 for this. 233 00:09:02,190 --> 00:09:03,330 You know, not much code, 234 00:09:03,330 --> 00:09:05,610 little bit of documentation, yep 235 00:09:05,610 --> 00:09:08,250 And so using the list of vulnerable projects 236 00:09:08,250 --> 00:09:09,870 that I was able 237 00:09:09,870 --> 00:09:12,060 to retrieve from running this query 238 00:09:12,060 --> 00:09:14,282 across the (indistinct) 239 00:09:14,282 --> 00:09:15,623 of projects that CodeQL indexes, 240 00:09:17,970 --> 00:09:19,382 I wrote a pull request generator. 241 00:09:19,382 --> 00:09:21,382 It was a Python based Wrapper over 'hub' 242 00:09:22,577 --> 00:09:23,760 which is GitHub's hub CLI. 243 00:09:23,760 --> 00:09:25,410 It had one nasty regular expression 244 00:09:25,410 --> 00:09:26,340 and a lot of logic for 245 00:09:26,340 --> 00:09:28,390 bouncing off of GitHub's rate limiter 246 00:09:29,490 --> 00:09:31,380 And this is the logic. 247 00:09:31,380 --> 00:09:32,340 There is an underlying engine, 248 00:09:32,340 --> 00:09:33,173 but at a high level, 249 00:09:33,173 --> 00:09:36,870 this is what allowed us to generate the commits 250 00:09:36,870 --> 00:09:38,343 and the pull requests. 251 00:09:39,182 --> 00:09:40,140 And this is the regular expression 252 00:09:40,140 --> 00:09:40,983 that we used. 253 00:09:42,362 --> 00:09:43,195 And you might ask 254 00:09:43,195 --> 00:09:44,028 why use a regular expression? 255 00:09:44,028 --> 00:09:46,082 We have XML parsers. 256 00:09:46,082 --> 00:09:48,480 And the reason that we use regular expressions 257 00:09:48,480 --> 00:09:49,360 is because 258 00:09:52,020 --> 00:09:54,990 when you parse XML into an XML parser, 259 00:09:54,990 --> 00:09:56,280 and then you make a modification 260 00:09:56,280 --> 00:09:57,900 and then you dump back out, 261 00:09:57,900 --> 00:10:00,813 all XML parsers have a standard output. 262 00:10:02,026 --> 00:10:03,420 And so you'll end up mass generating 263 00:10:03,420 --> 00:10:05,838 massive white space diffs 264 00:10:05,838 --> 00:10:06,960 across all of the files you're changing. 265 00:10:06,960 --> 00:10:09,060 And the maintainers will receive that as a pull request. 266 00:10:09,060 --> 00:10:11,430 And they'll be like, I'm not accepting this. 267 00:10:11,430 --> 00:10:12,630 Sure, you fix a security vulnerability, 268 00:10:12,630 --> 00:10:14,460 but it doesn't look like the code that I have. 269 00:10:14,460 --> 00:10:16,770 It doesn't match the editor format that I have. 270 00:10:16,770 --> 00:10:17,773 So unfortunately you have to use 271 00:10:17,773 --> 00:10:20,760 a regular expression to fix the issue. 272 00:10:20,760 --> 00:10:22,760 But the problem with regular expressions 273 00:10:24,226 --> 00:10:25,059 is that if you use regular expressions, 274 00:10:25,059 --> 00:10:26,140 now you have two problems, 275 00:10:27,346 --> 00:10:29,760 (laughing) 276 00:10:29,760 --> 00:10:30,603 but it worked. 277 00:10:32,986 --> 00:10:33,819 This is my GitHub feed 278 00:10:33,819 --> 00:10:34,800 for after I did this, 279 00:10:34,800 --> 00:10:36,630 just tons of pull requests, 280 00:10:36,630 --> 00:10:38,190 all of the same thing. 281 00:10:38,190 --> 00:10:39,993 And this is an example of the diff, 282 00:10:41,166 --> 00:10:44,243 you know, you can see the replacement of HTTP with HTTPS. 283 00:10:44,243 --> 00:10:45,300 And for this campaign, 284 00:10:45,300 --> 00:10:48,363 I generated 1,596 pull requests. 285 00:10:49,253 --> 00:10:51,693 And as of today, or little about a week ago, 286 00:10:53,423 --> 00:10:55,673 yeah, we have about a 40% merge rate for this 287 00:10:57,175 --> 00:10:59,130 and for engaging in this campaign and doing this on, 288 00:10:59,130 --> 00:11:00,840 in addition to the original bounty 289 00:11:00,840 --> 00:11:02,400 GitHub, additionally, bountied me 290 00:11:02,400 --> 00:11:04,953 an additional $4,000 for this work. 291 00:11:07,807 --> 00:11:09,459 So thank you. 292 00:11:09,459 --> 00:11:12,360 (audience clapping) 293 00:11:12,360 --> 00:11:14,730 So I got hooked on bulk pull request generation. 294 00:11:14,730 --> 00:11:15,720 I got hooked on this idea 295 00:11:15,720 --> 00:11:18,810 that we could actually fix these vulnerabilities 296 00:11:18,810 --> 00:11:20,163 at scale, across OSS. 297 00:11:21,480 --> 00:11:24,090 This is my GitHub contribution graph for 2020. 298 00:11:24,090 --> 00:11:24,923 You can see, 299 00:11:24,923 --> 00:11:27,570 I actually engaged in two campaigns this year 300 00:11:27,570 --> 00:11:29,460 and you know, you can see the actual impact 301 00:11:29,460 --> 00:11:31,323 of generating it, 302 00:11:32,724 --> 00:11:34,440 what it has on your contribution graph. 303 00:11:34,440 --> 00:11:35,500 So I have a problem 304 00:11:37,931 --> 00:11:38,764 I have ADHD, 305 00:11:39,611 --> 00:11:41,020 and that's not my problem. 306 00:11:41,020 --> 00:11:41,853 The problem, yeah. 307 00:11:41,853 --> 00:11:42,780 So ADHD is not my problem. 308 00:11:42,780 --> 00:11:43,810 The problem is 309 00:11:45,161 --> 00:11:46,710 that I love reading vulnerability disclosures. 310 00:11:46,710 --> 00:11:51,133 I go through them, the GitHub security advisories feed, 311 00:11:51,133 --> 00:11:52,410 and I can look at advisories 312 00:11:52,410 --> 00:11:54,120 and I can see read the vulnerability 313 00:11:54,120 --> 00:11:55,050 and I can be like, okay, 314 00:11:55,050 --> 00:11:56,790 I wonder where else this exists? 315 00:11:56,790 --> 00:11:58,290 And so I'll run a CodeQL query 316 00:11:58,290 --> 00:12:00,870 or I'll do a GitHub code search search. 317 00:12:00,870 --> 00:12:02,160 And the problem is 318 00:12:02,160 --> 00:12:04,740 I find too many vulnerabilities. 319 00:12:04,740 --> 00:12:06,180 There's more vulnerabilities 320 00:12:06,180 --> 00:12:08,580 than I can reasonably report as 321 00:12:08,580 --> 00:12:09,990 a security researcher. 322 00:12:09,990 --> 00:12:11,910 This is an example of a CodeQL query 323 00:12:11,910 --> 00:12:13,050 for Zip Slip. 324 00:12:13,050 --> 00:12:15,900 I can scroll through pages of these results 325 00:12:15,900 --> 00:12:17,070 across OSS. 326 00:12:17,070 --> 00:12:19,980 In fact, GitHub gave me a list of 900 projects 327 00:12:19,980 --> 00:12:20,813 that were potentially 328 00:12:20,813 --> 00:12:21,723 vulnerable to Zip Slip. 329 00:12:23,773 --> 00:12:25,980 So if I'm finding too many vulnerabilities, 330 00:12:25,980 --> 00:12:27,000 how do I fix this? 331 00:12:27,000 --> 00:12:27,833 How do I.... 332 00:12:27,833 --> 00:12:29,100 I can report one by one. 333 00:12:29,100 --> 00:12:32,370 I have to pick out which projects are worth reporting to, 334 00:12:32,370 --> 00:12:34,503 or I need automation. 335 00:12:36,745 --> 00:12:38,430 So now I wanna discuss with you 336 00:12:38,430 --> 00:12:39,990 a tool that has become something 337 00:12:39,990 --> 00:12:41,790 that I've really fell in love with 338 00:12:41,790 --> 00:12:43,680 because it's, it's allowed me to do this 339 00:12:43,680 --> 00:12:46,713 automated, accurate transformations at massive scale. 340 00:12:47,910 --> 00:12:49,080 So I wanna introduce you 341 00:12:49,080 --> 00:12:50,785 the tool 342 00:12:50,785 --> 00:12:51,702 OpenRewrite 343 00:12:52,825 --> 00:12:54,180 and OpenRewrite... 344 00:12:54,180 --> 00:12:56,210 It started out at Netflix. 345 00:12:56,210 --> 00:12:58,800 It was written by Jonathan Schneider 346 00:12:58,800 --> 00:13:01,440 and it was developed because Netflix, 347 00:13:01,440 --> 00:13:03,460 every single team at Netflix 348 00:13:04,462 --> 00:13:06,330 was given and enabled by the organization 349 00:13:06,330 --> 00:13:09,330 to write code in whatever format, style they wanted. 350 00:13:09,330 --> 00:13:10,800 As long as they owned the code, 351 00:13:10,800 --> 00:13:11,633 they were allowed to do 352 00:13:11,633 --> 00:13:12,466 whatever they wanted 353 00:13:12,466 --> 00:13:13,503 to develop software. 354 00:13:15,369 --> 00:13:16,470 And so if you need to update, for example, 355 00:13:16,470 --> 00:13:18,325 Google Guava, 356 00:13:18,325 --> 00:13:19,290 which traditionally has a breaking, 357 00:13:19,290 --> 00:13:21,840 API changes every time they release a new version, 358 00:13:21,840 --> 00:13:25,170 how do you get your entire organization up to date 359 00:13:25,170 --> 00:13:27,480 and using the latest version of a dependency 360 00:13:27,480 --> 00:13:30,130 that has a breaking API change every time you update? 361 00:13:31,693 --> 00:13:32,526 And so the answer was 362 00:13:32,526 --> 00:13:34,620 you need to not just update the diversion dependency, 363 00:13:34,620 --> 00:13:38,373 but you also need to update the code, to update. 364 00:13:40,001 --> 00:13:41,551 And so OpenRewrite was created. 365 00:13:42,570 --> 00:13:43,710 The traditional problem is 366 00:13:43,710 --> 00:13:45,990 that if you compile code, 367 00:13:45,990 --> 00:13:47,970 you'll see that the compiler produces 368 00:13:47,970 --> 00:13:50,190 what's called an abstract syntax tree. 369 00:13:50,190 --> 00:13:55,110 It's a representation of the code in a tree format. 370 00:13:55,110 --> 00:13:56,340 But the problem is 371 00:13:56,340 --> 00:13:59,730 you'll notice that if you grab this tree, 372 00:13:59,730 --> 00:14:02,310 if you wanted to dump it back out into text, 373 00:14:02,310 --> 00:14:04,140 you lose the formatting, 374 00:14:04,140 --> 00:14:04,973 the white space, 375 00:14:04,973 --> 00:14:06,236 the tabs, 376 00:14:06,236 --> 00:14:07,069 cause the compiler doesn't care 377 00:14:07,069 --> 00:14:08,253 about that information, right? 378 00:14:09,360 --> 00:14:10,990 And so OpenRewrite 379 00:14:13,230 --> 00:14:16,050 it uses the underlying AST that the Java compiler uses, 380 00:14:16,050 --> 00:14:18,960 but it also captures all the other stuff you need, 381 00:14:18,960 --> 00:14:19,793 the white space, 382 00:14:19,793 --> 00:14:20,877 the tabs, 383 00:14:20,877 --> 00:14:22,590 the spaces into the tree 384 00:14:22,590 --> 00:14:23,730 and preserves it 385 00:14:23,730 --> 00:14:25,230 so that you can take this tree 386 00:14:26,201 --> 00:14:28,800 and it'll transfer back and forth to the source code. 387 00:14:28,800 --> 00:14:32,073 So the white space and spaces are preserved. 388 00:14:33,600 --> 00:14:35,710 And you can also generate new code 389 00:14:36,564 --> 00:14:40,200 because as OpenRewrite is capturing the AST, 390 00:14:40,200 --> 00:14:41,250 it's also capturing 391 00:14:41,250 --> 00:14:42,840 the tabs, the spaces, 392 00:14:42,840 --> 00:14:44,250 how the format, 393 00:14:44,250 --> 00:14:45,360 do they use, 394 00:14:45,360 --> 00:14:47,910 does the developer use braces on new lines? 395 00:14:47,910 --> 00:14:49,563 So it can capture all of that. 396 00:14:50,591 --> 00:14:51,424 And as you're generating new code 397 00:14:51,424 --> 00:14:52,770 also generate it in a way 398 00:14:52,770 --> 00:14:54,192 that looks like the 399 00:14:54,192 --> 00:14:56,463 developing code around you. 400 00:14:59,337 --> 00:15:00,170 And on top of that, 401 00:15:00,170 --> 00:15:01,410 it's also Type- attributed. 402 00:15:01,410 --> 00:15:02,940 For example, this bit of code. 403 00:15:02,940 --> 00:15:04,320 If you just saw this, 404 00:15:04,320 --> 00:15:05,981 how do you know if this is 405 00:15:05,981 --> 00:15:08,430 log4j, slf4j, Log Back, 406 00:15:08,430 --> 00:15:09,920 they all have exactly the same API. 407 00:15:09,920 --> 00:15:11,940 So you need type attribution across the tree 408 00:15:11,940 --> 00:15:12,773 to also be able 409 00:15:12,773 --> 00:15:13,980 to make intelligent decisions 410 00:15:13,980 --> 00:15:17,130 about how you're gonna fix these vulnerabilities. 411 00:15:17,130 --> 00:15:18,913 And OpenRewrites AST 412 00:15:18,913 --> 00:15:23,760 is it's syntactically and semantically aware. 413 00:15:23,760 --> 00:15:26,313 You can see that just the syntax alone, 414 00:15:27,897 --> 00:15:29,333 when you have type attribution, 415 00:15:30,325 --> 00:15:31,410 you get a much more rich graph 416 00:15:31,410 --> 00:15:33,750 that lets you make much more intelligent decisions. 417 00:15:33,750 --> 00:15:35,220 Actually, the image on the right 418 00:15:35,220 --> 00:15:37,320 is missing about 6,000 lines 419 00:15:37,320 --> 00:15:39,120 because it would just be a mess. 420 00:15:39,120 --> 00:15:40,793 You wouldn't even be able to see it. 421 00:15:41,970 --> 00:15:43,160 And then on top of that, 422 00:15:43,160 --> 00:15:46,950 if you're trying to replace code, 423 00:15:46,950 --> 00:15:51,150 you need to be able to take new Java code 424 00:15:51,150 --> 00:15:54,843 and put it into the AST to fix these vulnerabilities. 425 00:15:55,777 --> 00:15:59,100 And so you need a way to generate new ASTs in an easy way. 426 00:15:59,100 --> 00:16:00,720 As an example for Zip Slip, 427 00:16:00,720 --> 00:16:02,760 which I'm gonna talk to you about a little bit later, 428 00:16:02,760 --> 00:16:04,710 we need to inject this bit of code 429 00:16:04,710 --> 00:16:08,313 into the surrounding code. 430 00:16:09,521 --> 00:16:11,040 And so how do we do that in a way that's easy 431 00:16:11,040 --> 00:16:12,390 and you don't have to write a ton of code 432 00:16:12,390 --> 00:16:13,860 to generate a bunch of graph nodes 433 00:16:13,860 --> 00:16:15,450 to inject into the tree? 434 00:16:15,450 --> 00:16:16,800 And so OpenRewrite, 435 00:16:16,800 --> 00:16:18,450 it comes with a templating engine 436 00:16:18,450 --> 00:16:21,510 that lets you just put a string in your code. 437 00:16:21,510 --> 00:16:25,230 And the templating engine will generate new code 438 00:16:25,230 --> 00:16:27,780 that matches the surrounding style 439 00:16:27,780 --> 00:16:30,230 of the developer's code that you're working with. 440 00:16:31,225 --> 00:16:32,220 And then if you wanna inject that into the code, 441 00:16:32,220 --> 00:16:33,780 it has a coordinate system that says 442 00:16:33,780 --> 00:16:37,020 place this chunk of code after a certain location 443 00:16:37,020 --> 00:16:37,853 in the code. 444 00:16:37,853 --> 00:16:40,560 And that's all that's required to fix this, 445 00:16:40,560 --> 00:16:42,420 to add this little bit of code, 446 00:16:42,420 --> 00:16:43,353 to fix Zip Slip. 447 00:16:46,020 --> 00:16:50,640 And so it lets us transform code like this 448 00:16:50,640 --> 00:16:52,110 and add that fix 449 00:16:52,110 --> 00:16:53,910 where it's required. 450 00:16:53,910 --> 00:16:55,830 So what's possible now? 451 00:16:55,830 --> 00:16:58,230 What other vulnerabilities can we fix with this unlock 452 00:16:58,230 --> 00:17:00,960 that OpenRewrite provides us? 453 00:17:00,960 --> 00:17:02,580 I'm gonna talk to you about three different vulnerabilities 454 00:17:02,580 --> 00:17:04,080 that I tackled with OpenRewrite 455 00:17:04,080 --> 00:17:06,270 to fix widespread, common security vulnerabilities 456 00:17:06,270 --> 00:17:07,590 across OSS. 457 00:17:07,590 --> 00:17:10,500 The first one is called Temporary Directory Hijacking. 458 00:17:10,500 --> 00:17:13,076 The second one is Partial Path Traversal 459 00:17:13,076 --> 00:17:15,330 and the third one is called Zip Slip. 460 00:17:15,330 --> 00:17:17,730 Let's start with, Temporary Directory Hijacking. 461 00:17:19,781 --> 00:17:22,060 So the basis of Temporary Directory Hijacking 462 00:17:23,321 --> 00:17:24,660 is that the system temp directory 463 00:17:24,660 --> 00:17:25,830 on Unix-Like systems 464 00:17:25,830 --> 00:17:27,513 is shared between all users. 465 00:17:31,573 --> 00:17:33,870 So this is Temporary Directory Hijacking. 466 00:17:33,870 --> 00:17:35,760 And the reason that you'll find this code 467 00:17:35,760 --> 00:17:38,850 in lots of OSS and lots of closed source projects 468 00:17:38,850 --> 00:17:41,190 is that prior to Java, 1.7, 469 00:17:41,190 --> 00:17:43,350 there did not exist a public API 470 00:17:43,350 --> 00:17:44,460 in the Java standard library 471 00:17:44,460 --> 00:17:46,680 to create a temporary directory. 472 00:17:46,680 --> 00:17:47,790 So what people did is 473 00:17:47,790 --> 00:17:50,880 they created a temporary file that uses a C S P R N G 474 00:17:50,880 --> 00:17:52,743 to generate a temporary file name. 475 00:17:53,962 --> 00:17:55,712 So guaranteed to be uniquely random 476 00:17:56,637 --> 00:17:58,350 and non colliding with any of the other files 477 00:17:58,350 --> 00:18:00,870 and they call delete and they call mkdir. 478 00:18:00,870 --> 00:18:03,420 And the reason this vulnerability is so prevalent 479 00:18:03,420 --> 00:18:05,670 is because if you looked up on stack overflow, 480 00:18:05,670 --> 00:18:08,280 how do you create a temporary directory? 481 00:18:08,280 --> 00:18:10,380 you'd unintentionally get a vulnerability. 482 00:18:13,525 --> 00:18:15,000 And so why is this vulnerable? 483 00:18:15,000 --> 00:18:15,833 This is vulnerable 484 00:18:15,833 --> 00:18:17,910 because there's a race condition 485 00:18:17,910 --> 00:18:18,743 here. 486 00:18:19,800 --> 00:18:23,190 You can have another local user on the system 487 00:18:23,190 --> 00:18:25,330 waiting for the deletion call 488 00:18:27,660 --> 00:18:29,060 When you call mkdir... 489 00:18:30,865 --> 00:18:33,690 lost my place.... 490 00:18:33,690 --> 00:18:35,100 When you call mkdir 491 00:18:35,100 --> 00:18:35,940 there's a race condition 492 00:18:35,940 --> 00:18:37,860 between the Java process and the attacker 493 00:18:37,860 --> 00:18:40,272 to create that directory first, 494 00:18:40,272 --> 00:18:41,970 because if the Java process fails 495 00:18:41,970 --> 00:18:45,723 or if the Java process is beaten, 496 00:18:46,812 --> 00:18:47,645 instead of throwing an exception, 497 00:18:47,645 --> 00:18:48,780 it returns false. 498 00:18:48,780 --> 00:18:49,860 So what's the fix? 499 00:18:49,860 --> 00:18:50,940 Well, it is a simple fix, 500 00:18:50,940 --> 00:18:52,380 but it's imperfect. 501 00:18:52,380 --> 00:18:54,600 It does fix Temporary Directory Hijacking. 502 00:18:54,600 --> 00:18:56,140 But the problem is 503 00:18:56,140 --> 00:18:57,330 that the mkdir will still use 504 00:18:57,330 --> 00:18:59,520 the default (indistinct) permissions 505 00:18:59,520 --> 00:19:00,570 when it's creating the directory. 506 00:19:00,570 --> 00:19:02,700 And so the directory will be exposed to all, 507 00:19:02,700 --> 00:19:05,430 will still be visible to all local users. 508 00:19:05,430 --> 00:19:07,290 And so instead of Temporary Directory Hijacking, 509 00:19:07,290 --> 00:19:10,440 you have temporary directory information disclosure. 510 00:19:10,440 --> 00:19:12,000 So what's the true fix ? 511 00:19:12,000 --> 00:19:14,400 This API was introduced in Java 1.7. 512 00:19:14,400 --> 00:19:16,263 Java 1.7 is very old, 513 00:19:17,217 --> 00:19:18,480 it's I think end of life, even now. 514 00:19:18,480 --> 00:19:20,400 So this APIs been around for a long time. 515 00:19:20,400 --> 00:19:21,450 You can safely use it 516 00:19:21,450 --> 00:19:23,100 and unless you create a temporary directory 517 00:19:23,100 --> 00:19:26,250 that also sets the POS exhibitions on the file correctly 518 00:19:26,250 --> 00:19:29,580 to be secure and not visible to other local users. 519 00:19:29,580 --> 00:19:32,130 And so I got a bunch of CVs for this vulnerability. 520 00:19:32,970 --> 00:19:34,740 I have a lot of history of getting vulnerabilities, 521 00:19:34,740 --> 00:19:35,573 but for this one, 522 00:19:35,573 --> 00:19:37,770 I actually reported it to a bunch of projects. 523 00:19:37,770 --> 00:19:39,900 But again, I had this problem where 524 00:19:39,900 --> 00:19:42,685 even though I reported to all these projects, 525 00:19:42,685 --> 00:19:44,850 there was still more vulnerable projects 526 00:19:44,850 --> 00:19:46,713 than I could reasonably deal with. 527 00:19:48,085 --> 00:19:50,010 And so I said, all right, let's generate some pull requests. 528 00:19:50,010 --> 00:19:51,423 So for this fix, 529 00:19:52,633 --> 00:19:55,233 I generated 64 pull requests to fix this across OSS. 530 00:19:56,081 --> 00:19:57,570 And they're probably more possible on top of this, 531 00:19:57,570 --> 00:19:58,470 but for now, 532 00:19:58,470 --> 00:19:59,920 this is as far as I've gotten 533 00:20:00,897 --> 00:20:02,700 and I plan to do more of this in the future, 534 00:20:02,700 --> 00:20:03,870 But still even, 535 00:20:03,870 --> 00:20:04,710 consider this, 536 00:20:04,710 --> 00:20:06,843 reporting to 64 projects, 537 00:20:08,199 --> 00:20:10,230 each time like each one being reported 538 00:20:10,230 --> 00:20:11,673 takes a lot of time. 539 00:20:13,496 --> 00:20:15,810 So multiply my time X 64 projects. 540 00:20:15,810 --> 00:20:17,550 It's a lot of time spent 541 00:20:17,550 --> 00:20:18,633 that this has saved. 542 00:20:20,190 --> 00:20:22,121 So the second vulnerability, 543 00:20:22,121 --> 00:20:22,954 oh wait, actually I wanted to. 544 00:20:22,954 --> 00:20:24,491 So the example, 545 00:20:24,491 --> 00:20:25,324 this is an example of the diff generated 546 00:20:25,324 --> 00:20:27,070 and you can see in this change 547 00:20:28,781 --> 00:20:30,773 where we've deleted the delete and the mkdir, 548 00:20:31,737 --> 00:20:34,890 and we've put in place this fixed code 549 00:20:34,890 --> 00:20:36,890 and here's an even more complicated fix. 550 00:20:38,199 --> 00:20:39,390 You can see that we've deleted the IF blocks 551 00:20:39,390 --> 00:20:41,220 that are no longer required 552 00:20:41,220 --> 00:20:43,050 and put in place that single line of code 553 00:20:43,050 --> 00:20:44,103 that's now required. 554 00:20:46,110 --> 00:20:48,180 So the second vulnerability 555 00:20:48,180 --> 00:20:49,740 that I want to introduce you all to 556 00:20:49,740 --> 00:20:51,483 is called partial path traversal. 557 00:20:53,670 --> 00:20:55,590 So partial path traversal, 558 00:20:55,590 --> 00:20:57,690 let's assume that you have two users on a local system, 559 00:20:57,690 --> 00:21:00,003 user Sam and user Samantha, 560 00:21:01,857 --> 00:21:03,000 and you want to isolate your code 561 00:21:03,000 --> 00:21:06,303 to only allow an attacker to access user Sam. 562 00:21:07,200 --> 00:21:08,910 Partial patch traversal allows an attacker 563 00:21:08,910 --> 00:21:11,793 to access a sibling directory with the same prefix. 564 00:21:12,731 --> 00:21:16,230 So for example, you have user Sam and user Samantha. 565 00:21:16,230 --> 00:21:17,100 This vulnerability exists 566 00:21:17,100 --> 00:21:21,333 because user Sam is a prefix of user Samantha, 567 00:21:22,290 --> 00:21:24,120 and this is the vulnerable code. 568 00:21:24,120 --> 00:21:28,240 It's vulnerable because when you take a file 569 00:21:30,133 --> 00:21:32,130 and you call getcanonicalpath on it, 570 00:21:32,130 --> 00:21:33,690 it returns a string. 571 00:21:33,690 --> 00:21:35,530 And that string you'll notice 572 00:21:37,110 --> 00:21:38,670 it normalizes the path, 573 00:21:38,670 --> 00:21:40,290 So it removes the dot dots, 574 00:21:40,290 --> 00:21:41,880 any path traversal payloads, 575 00:21:41,880 --> 00:21:44,133 but it also drops the trailing slash. 576 00:21:46,677 --> 00:21:49,050 And so when this code ends up being used in a guard, 577 00:21:49,050 --> 00:21:51,310 you can see that when you take user Sam 578 00:21:52,389 --> 00:21:53,430 and then you have an attacker supply 579 00:21:53,430 --> 00:21:54,430 User Samantha 580 00:21:56,277 --> 00:21:57,219 when getCanonicalPath gets called 581 00:21:57,219 --> 00:21:59,763 and the getthepath gets normalized. 582 00:22:00,810 --> 00:22:04,050 That starts with Path-Check passes. 583 00:22:04,050 --> 00:22:06,720 And so the exception doesn't get thrown. 584 00:22:06,720 --> 00:22:09,030 And so what's the fix for this? 585 00:22:09,030 --> 00:22:09,863 Well, the fix, 586 00:22:09,863 --> 00:22:11,733 looking back at the vulnerable code. 587 00:22:13,380 --> 00:22:14,430 The first fix you can do 588 00:22:14,430 --> 00:22:16,383 is you can just add the slash back in. 589 00:22:18,000 --> 00:22:19,870 However, the better fix for this 590 00:22:20,893 --> 00:22:23,073 is to use the Java path API, 591 00:22:24,357 --> 00:22:26,220 which is instead of using getcanonical path, 592 00:22:26,220 --> 00:22:27,450 use getcanonical file, 593 00:22:27,450 --> 00:22:29,250 and then call .topath on it, 594 00:22:29,250 --> 00:22:31,503 which uses the Java object. 595 00:22:32,817 --> 00:22:33,650 And when you call startsWith on it, 596 00:22:35,235 --> 00:22:36,068 it does path comparisons 597 00:22:36,068 --> 00:22:36,901 instead of string comparisons, 598 00:22:36,901 --> 00:22:38,340 which is going to be safe. 599 00:22:38,340 --> 00:22:40,190 So how do we find this vulnerability? 600 00:22:41,715 --> 00:22:43,027 Well, first we're looking for a string 601 00:22:43,027 --> 00:22:44,730 .startsWith call 602 00:22:44,730 --> 00:22:45,750 but then we need to look for 603 00:22:45,750 --> 00:22:47,910 before and inside of the 604 00:22:47,910 --> 00:22:49,860 arguments, a call to .getCanonicalPath. 605 00:22:52,320 --> 00:22:53,610 And then on top of that, 606 00:22:53,610 --> 00:22:55,020 we also wanna look for cases 607 00:22:55,020 --> 00:22:56,790 when we're trying to fix this vulnerability. 608 00:22:56,790 --> 00:22:59,280 We wanna look for cases where the file separator 609 00:22:59,280 --> 00:23:00,113 is not present, 610 00:23:00,113 --> 00:23:00,990 because if it is present, 611 00:23:00,990 --> 00:23:02,203 you don't wanna fix.... 612 00:23:03,059 --> 00:23:03,960 At the core, you don't wanna fix a vulnerability 613 00:23:03,960 --> 00:23:06,810 that's not there, right? 614 00:23:06,810 --> 00:23:09,900 but it can't be that easy, right? 615 00:23:09,900 --> 00:23:11,850 What if a developer, 616 00:23:11,850 --> 00:23:12,930 because developers are gonna write code 617 00:23:12,930 --> 00:23:13,860 in a lot of different ways, 618 00:23:13,860 --> 00:23:15,310 what happens if a developer 619 00:23:16,230 --> 00:23:18,720 extracts that code into a variable 620 00:23:18,720 --> 00:23:22,200 or what if they pull the other argument into a variable 621 00:23:22,200 --> 00:23:25,230 or they have the fix in a variable, 622 00:23:25,230 --> 00:23:28,650 we need something new to make it possible to fix this. 623 00:23:28,650 --> 00:23:30,453 So we need data flow analysis. 624 00:23:31,350 --> 00:23:33,810 Data flow analysis allows us to 625 00:23:33,810 --> 00:23:38,160 track the assignment of values through the program 626 00:23:38,160 --> 00:23:41,250 and see what the final value will be at runtime. 627 00:23:41,250 --> 00:23:44,430 So we can see that dircanonical is being assigned 628 00:23:44,430 --> 00:23:47,370 from that getcanonical path call. 629 00:23:47,370 --> 00:23:50,656 And additionally, you can do that for other things, 630 00:23:50,656 --> 00:23:52,740 and it lets you do this for intermediate steps 631 00:23:52,740 --> 00:23:55,590 that may be even more complicated than this. 632 00:23:55,590 --> 00:23:57,120 So data flow allows us to uncover 633 00:23:57,120 --> 00:23:58,140 hard to find vulnerabilities 634 00:23:58,140 --> 00:24:00,270 and to prevent false positives. 635 00:24:00,270 --> 00:24:03,750 And this is the API for data flow for OpenRewrite, 636 00:24:03,750 --> 00:24:05,370 something that I developed based upon 637 00:24:05,370 --> 00:24:06,960 CodeQL's, data flow analysis API. 638 00:24:06,960 --> 00:24:10,290 So if you learn CodeQL or you learn OpenRewrite, 639 00:24:10,290 --> 00:24:12,330 you can translate your knowledge very easily back and forth 640 00:24:12,330 --> 00:24:14,403 between these two paradigms, 641 00:24:15,778 --> 00:24:16,800 which makes fixing these vulnerabilities 642 00:24:16,800 --> 00:24:19,750 and identifying these vulnerabilities significantly easier. 643 00:24:20,612 --> 00:24:22,680 And so this is an example of putting it all together. 644 00:24:22,680 --> 00:24:25,170 We're able to replace this 645 00:24:25,170 --> 00:24:28,500 vulnerable call with the safe version. 646 00:24:28,500 --> 00:24:33,240 I want to give you a case study on this vulnerability, 647 00:24:33,240 --> 00:24:37,020 an example from the AWS Java SDK. 648 00:24:37,020 --> 00:24:38,223 It has a CV number. 649 00:24:39,060 --> 00:24:41,673 I found this vulnerability in the Amazon SDK. 650 00:24:43,110 --> 00:24:44,250 It was for the transfer manager, 651 00:24:44,250 --> 00:24:47,013 which is used to download the contents of AWS buckets. 652 00:24:48,117 --> 00:24:50,400 And they had a check in there to prevent path traversal. 653 00:24:50,400 --> 00:24:52,140 If the AWS bucket key 654 00:24:52,140 --> 00:24:54,693 was potentially a path traversal payload. 655 00:24:56,010 --> 00:24:58,140 And so you can see this logic was vulnerable 656 00:24:58,140 --> 00:24:59,920 to partial path traversal 657 00:25:01,507 --> 00:25:02,828 because this leavesRoot logic was used in this guard 658 00:25:02,828 --> 00:25:07,828 to check if the AWS S3 key 659 00:25:08,610 --> 00:25:09,963 was outside of the path. 660 00:25:11,046 --> 00:25:12,772 And so we got a vulnerability for this. 661 00:25:12,772 --> 00:25:14,430 The Amazon security team was very pleasant to work with. 662 00:25:14,430 --> 00:25:15,630 However, with any good story, 663 00:25:15,630 --> 00:25:18,510 there was a little bit of vulnerability disclosure drama. 664 00:25:18,510 --> 00:25:20,100 And this story I had to throw it in there, 665 00:25:20,100 --> 00:25:22,100 was too funny not to share with you all. 666 00:25:23,932 --> 00:25:24,990 So this is my email conversation 667 00:25:24,990 --> 00:25:27,360 with the Amazon web services security team. 668 00:25:27,360 --> 00:25:29,550 We'd like to award you a bug bounty for this, 669 00:25:29,550 --> 00:25:31,530 however, you need to sign an NDA. 670 00:25:31,530 --> 00:25:32,920 And I said, 671 00:25:32,920 --> 00:25:34,410 I don't normally agree to NDAs. 672 00:25:34,410 --> 00:25:36,570 Can I read it first before potentially agreeing? 673 00:25:36,570 --> 00:25:37,740 And they said, 674 00:25:37,740 --> 00:25:39,750 we're unable to share bug bounty program NDAs 675 00:25:39,750 --> 00:25:41,880 since it and other contract documents 676 00:25:41,880 --> 00:25:44,948 are considered sensitive by the legal team. 677 00:25:44,948 --> 00:25:47,948 (audience laughing) 678 00:25:50,345 --> 00:25:53,345 (audience clapping) 679 00:26:00,652 --> 00:26:03,243 - Yeah. (laughing) 680 00:26:05,648 --> 00:26:09,100 So yeah, again too funny not to share with you all. 681 00:26:11,452 --> 00:26:12,390 I have asked the Amazon web services team 682 00:26:12,390 --> 00:26:14,168 instead of bounting me 683 00:26:14,168 --> 00:26:15,001 to double the bounty amount 684 00:26:15,001 --> 00:26:16,380 and just donate it to 685 00:26:16,380 --> 00:26:18,060 the Electronic Frontier Foundation. 686 00:26:18,060 --> 00:26:20,040 They've yet to get back to me on that particular front. 687 00:26:20,040 --> 00:26:22,293 So we'll see what happens. 688 00:26:23,244 --> 00:26:24,240 (laughing) 689 00:26:24,240 --> 00:26:25,073 Yeah, right. 690 00:26:25,073 --> 00:26:25,906 Thank you. 691 00:26:26,880 --> 00:26:28,464 So the third vulnerability 692 00:26:28,464 --> 00:26:29,910 that I wanna share with you all is zip slip. 693 00:26:29,910 --> 00:26:32,484 So zip slip is an old vulnerability. 694 00:26:32,484 --> 00:26:35,793 It's been around since Frack magazine many, many years ago. 695 00:26:37,356 --> 00:26:38,880 And the SNCC team actually did a bunch of research 696 00:26:38,880 --> 00:26:40,950 about zip slip a couple years ago, 697 00:26:40,950 --> 00:26:42,390 and found a bunch of projects 698 00:26:42,390 --> 00:26:44,512 that were unzipping logic that 699 00:26:44,512 --> 00:26:45,630 were vulnerable to this. 700 00:26:45,630 --> 00:26:47,500 Zip slip fundamentally is not 701 00:26:48,412 --> 00:26:49,350 a partial path traversal vulnerability, 702 00:26:49,350 --> 00:26:51,930 but it's a path traversal vulnerability 703 00:26:51,930 --> 00:26:54,150 while unpacking zip files. 704 00:26:54,150 --> 00:26:57,930 However, partial path traversal can exist in zip slip. 705 00:26:57,930 --> 00:26:59,520 And some of the cases that I found 706 00:26:59,520 --> 00:27:01,380 that the SNCC team reported to 707 00:27:01,380 --> 00:27:03,930 when I looked at the code again, several years later, 708 00:27:03,930 --> 00:27:04,950 I found that that code, 709 00:27:04,950 --> 00:27:08,048 even though it had been patched against path traversal, 710 00:27:08,048 --> 00:27:09,450 it still was vulnerable to partial path traversal, 711 00:27:09,450 --> 00:27:11,280 which we discussed earlier. 712 00:27:11,280 --> 00:27:14,730 And so this is the vulnerable code for zip slip and Java. 713 00:27:14,730 --> 00:27:16,540 And the reason it's vulnerable is 714 00:27:18,120 --> 00:27:20,010 because you have the name of a zip entry 715 00:27:20,010 --> 00:27:22,203 flowing to the creation of a file, 716 00:27:23,909 --> 00:27:26,552 that getName can be a pass traversal payload. 717 00:27:26,552 --> 00:27:29,763 And that's flows to the creation of a file output stream. 718 00:27:31,952 --> 00:27:34,890 And so if that's a pass traversal payload, 719 00:27:34,890 --> 00:27:38,400 then you can overwrite the contents of an execution file. 720 00:27:38,400 --> 00:27:39,630 And then you can get code execution. 721 00:27:39,630 --> 00:27:40,980 So zip slip, 722 00:27:40,980 --> 00:27:42,030 although not directly, 723 00:27:42,030 --> 00:27:43,740 it can lead to code execution 724 00:27:43,740 --> 00:27:45,930 if you overwrite the right files. 725 00:27:45,930 --> 00:27:47,580 And zip slip is complicated. 726 00:27:47,580 --> 00:27:49,380 And the reason that it's complicated is 727 00:27:49,380 --> 00:27:51,510 that in order to fix it, 728 00:27:51,510 --> 00:27:54,660 you need to add this chunk of logic to the code. 729 00:27:54,660 --> 00:27:57,730 However, the problem with zip slip in this case 730 00:27:59,802 --> 00:28:01,530 is that, this is a valid fix to this vulnerability. 731 00:28:01,530 --> 00:28:04,200 And you'll find this in OSS code, 732 00:28:04,200 --> 00:28:06,330 but this is also a valid fix. 733 00:28:06,330 --> 00:28:09,810 So how, again, we don't wanna fix non vulnerable code. 734 00:28:09,810 --> 00:28:11,070 So how do you identify, 735 00:28:11,070 --> 00:28:13,830 is this vulnerable or is this not vulnerable? 736 00:28:13,830 --> 00:28:15,570 And so we need something new 737 00:28:15,570 --> 00:28:16,860 that we haven't talked about yet. 738 00:28:16,860 --> 00:28:18,603 It's called control flow analysis. 739 00:28:19,500 --> 00:28:20,880 Control flow analysis 740 00:28:20,880 --> 00:28:23,040 lets us determine the difference between 741 00:28:23,040 --> 00:28:24,300 the vulnerable code 742 00:28:24,300 --> 00:28:25,133 on the left 743 00:28:25,133 --> 00:28:27,840 and the non vulnerable code on the right. 744 00:28:27,840 --> 00:28:29,384 So control flow analysis. 745 00:28:29,384 --> 00:28:31,510 What you do is 746 00:28:32,564 --> 00:28:34,200 you walk over the AST and you build a graph 747 00:28:36,556 --> 00:28:37,456 or you build a tree or graph. 748 00:28:37,456 --> 00:28:39,630 It's a graph of the connected nodes 749 00:28:39,630 --> 00:28:40,950 where you have basic blocks, 750 00:28:40,950 --> 00:28:42,720 which are the set of contiguous operations 751 00:28:42,720 --> 00:28:44,340 that are gonna occur 752 00:28:44,340 --> 00:28:45,810 in order 753 00:28:45,810 --> 00:28:48,000 followed by any of the conditional nodes 754 00:28:48,000 --> 00:28:49,233 that exist in the logic. 755 00:28:50,776 --> 00:28:52,620 And so looking at partial path traversal 756 00:28:53,820 --> 00:28:54,985 or sorry, 757 00:28:54,985 --> 00:28:56,130 looking at zip slip, 758 00:28:56,130 --> 00:28:57,000 you can see that 759 00:28:57,000 --> 00:29:00,450 this is an example of the control flow analysis graph 760 00:29:00,450 --> 00:29:02,940 built for this non vulnerable code. 761 00:29:02,940 --> 00:29:07,260 And so we're able to diverse this graph in our logic 762 00:29:07,260 --> 00:29:08,670 and determine that, 763 00:29:08,670 --> 00:29:09,663 oh, hey look, 764 00:29:10,860 --> 00:29:13,830 there is a guard in place that when it's false 765 00:29:13,830 --> 00:29:15,812 throws an exception. 766 00:29:15,812 --> 00:29:17,310 So we are not reaching the vulnerable code 767 00:29:17,310 --> 00:29:19,760 where we're creating that new file output stream. 768 00:29:21,854 --> 00:29:22,920 And so when we put all this together, 769 00:29:22,920 --> 00:29:26,553 we're able to not fix code that's not vulnerable. 770 00:29:27,404 --> 00:29:28,320 And we are able to fix code that is vulnerable, 771 00:29:28,320 --> 00:29:29,790 which is what we want to do. 772 00:29:29,790 --> 00:29:32,250 And this is an example of the diff generated 773 00:29:32,250 --> 00:29:33,573 to fix this vulnerability. 774 00:29:34,652 --> 00:29:35,924 And here's another one 775 00:29:35,924 --> 00:29:36,757 where not only have we fixed the vulnerability, 776 00:29:36,757 --> 00:29:38,933 we've also cleaned up the code a little bit around it. 777 00:29:40,952 --> 00:29:42,030 And so I wanna talk to you next about 778 00:29:42,030 --> 00:29:43,770 actually doing pull request generation. 779 00:29:43,770 --> 00:29:45,840 Cause if you've got security vulnerabilities, 780 00:29:45,840 --> 00:29:47,343 everybody gets a pull request. 781 00:29:48,180 --> 00:29:50,430 (laughing) 782 00:29:51,480 --> 00:29:53,040 So there's a problem with pull request generation. 783 00:29:53,040 --> 00:29:54,420 And one of the problems is 784 00:29:54,420 --> 00:29:56,703 how fast can we generate pull requests? 785 00:29:58,904 --> 00:30:00,390 So as a part of generating pull requests, 786 00:30:00,390 --> 00:30:03,030 there's three major types of operation. 787 00:30:03,030 --> 00:30:04,170 You have to make file IO, 788 00:30:04,170 --> 00:30:06,333 Git operations and GitHub API calls. 789 00:30:07,620 --> 00:30:09,030 The first one is pretty free. 790 00:30:09,030 --> 00:30:09,863 The second one, 791 00:30:09,863 --> 00:30:11,010 GIT operations against GitHub 792 00:30:11,010 --> 00:30:13,260 are completely free as well. 793 00:30:13,260 --> 00:30:14,130 GitHub does not rate limit 794 00:30:14,130 --> 00:30:16,260 and GitHub has rate limit, 795 00:30:16,260 --> 00:30:19,020 which is very annoying, on their API calls. 796 00:30:19,020 --> 00:30:20,190 So the first one you need to do, 797 00:30:20,190 --> 00:30:22,470 check out, then download the code Repository. 798 00:30:22,470 --> 00:30:24,480 Then you need to Branch.Apply the diff 799 00:30:24,480 --> 00:30:25,950 and commit the change. 800 00:30:25,950 --> 00:30:27,810 Then you need to fork the repository 801 00:30:27,810 --> 00:30:30,376 and rename the repository on GitHub. 802 00:30:30,376 --> 00:30:31,209 And the reason this is important is 803 00:30:31,209 --> 00:30:32,520 because when you're forking 804 00:30:32,520 --> 00:30:36,060 hundreds or thousands of repositories, 805 00:30:36,060 --> 00:30:37,950 you're gonna end up with name conflicts. 806 00:30:37,950 --> 00:30:40,350 And so if you don't rename them, 807 00:30:40,350 --> 00:30:41,550 GitHub's gonna come back and say, 808 00:30:41,550 --> 00:30:43,320 there's already a fork with that name. 809 00:30:43,320 --> 00:30:44,610 So you have to rename it. 810 00:30:44,610 --> 00:30:46,830 And unfortunately GitHub does not offer an API 811 00:30:46,830 --> 00:30:50,940 to do both of those steps in one API call. 812 00:30:50,940 --> 00:30:52,680 And then you push the changes 813 00:30:52,680 --> 00:30:55,170 and then you create a pull request on GitHub. 814 00:30:55,170 --> 00:30:56,760 And so you'll notice that 815 00:30:56,760 --> 00:31:00,150 there's three API calls here that are rate limited 816 00:31:00,150 --> 00:31:01,680 and GitHub asks that you wait 817 00:31:01,680 --> 00:31:05,040 at least one second, per user per request. 818 00:31:05,040 --> 00:31:06,750 So that means that for every pull request you're generating, 819 00:31:06,750 --> 00:31:09,570 you're gonna have to wait at least three seconds. 820 00:31:09,570 --> 00:31:11,250 And on top of that, 821 00:31:11,250 --> 00:31:14,220 there's additional secondary and tertiary rate limits 822 00:31:14,220 --> 00:31:15,330 that they document 823 00:31:15,330 --> 00:31:18,250 with mixed success 824 00:31:20,910 --> 00:31:23,510 and that you have to be aware of and just deal with. 825 00:31:25,364 --> 00:31:27,514 So if anyone from GitHub's in the audience, 826 00:31:28,800 --> 00:31:30,180 (laughing) 827 00:31:30,180 --> 00:31:31,440 it would make my life a lot easier 828 00:31:31,440 --> 00:31:32,273 as a security researcher. 829 00:31:32,273 --> 00:31:35,150 If you just backed off a little bit on your rate limiting. 830 00:31:37,064 --> 00:31:37,897 So we've made it this far, 831 00:31:37,897 --> 00:31:39,420 we've detected the vulnerability, 832 00:31:39,420 --> 00:31:40,720 the style's been detected. 833 00:31:42,572 --> 00:31:43,405 The code's been fixed 834 00:31:43,405 --> 00:31:44,340 and a diffs been generated 835 00:31:44,340 --> 00:31:47,430 and the rate limit, although annoyingly 836 00:31:47,430 --> 00:31:48,663 has been bypassed. 837 00:31:49,964 --> 00:31:50,864 How do we fix this 838 00:31:50,864 --> 00:31:53,223 for all the repositories across GitHub? 839 00:31:54,882 --> 00:31:56,700 And I wanna introduce you, Moderne. 840 00:31:56,700 --> 00:31:59,580 Moderne is a free for OSS projects, 841 00:31:59,580 --> 00:32:00,820 Saas offering 842 00:32:02,940 --> 00:32:05,250 that currently indexes over 7,000 repositories. 843 00:32:05,250 --> 00:32:08,700 And it lets you run OpenRewrite transformations at scale, 844 00:32:08,700 --> 00:32:11,403 and it lets you generate and update pull requests. 845 00:32:12,930 --> 00:32:16,470 Moderne has over 800 OpenRewrite recipes, 846 00:32:16,470 --> 00:32:18,060 including complete framework migrations. 847 00:32:18,060 --> 00:32:20,130 And the reason that framework migrations 848 00:32:20,130 --> 00:32:21,360 are important is, 849 00:32:21,360 --> 00:32:22,413 take for example, 850 00:32:26,340 --> 00:32:27,173 excuse me, 851 00:32:27,173 --> 00:32:28,006 Spring. 852 00:32:28,006 --> 00:32:30,060 If you wanna use the latest version of spring, 853 00:32:30,060 --> 00:32:32,372 unfortunately the latest version of Spring 854 00:32:32,372 --> 00:32:35,550 requires the latest version of JUnit, 855 00:32:35,550 --> 00:32:36,660 which is a testing framework. 856 00:32:36,660 --> 00:32:38,310 That's JUnit 4 and JUnit5 857 00:32:38,310 --> 00:32:39,900 and there's a completely different API 858 00:32:39,900 --> 00:32:41,100 between the two of them. 859 00:32:42,512 --> 00:32:43,770 And so if you wanna be in the latest version of Spring, 860 00:32:43,770 --> 00:32:45,300 which as security practitioners, 861 00:32:45,300 --> 00:32:46,410 we probably all heard about 862 00:32:46,410 --> 00:32:49,950 why keeping your version of Spring up to date is important. 863 00:32:49,950 --> 00:32:52,290 You also need to keep your test framework up to date. 864 00:32:52,290 --> 00:32:55,951 And if you wanna migrate all of your code, 865 00:32:55,951 --> 00:32:57,418 you have to migrate your entire code from 866 00:32:57,418 --> 00:33:00,452 JUnit 4 to JUnit 5 to be on the latest version of Spring 867 00:33:00,452 --> 00:33:02,850 And so even your indirect test dependencies 868 00:33:02,850 --> 00:33:05,460 can be a security risk if you can't update them 869 00:33:05,460 --> 00:33:06,870 because it'll prevent you from updating 870 00:33:06,870 --> 00:33:09,150 the critical opponents like Spring. 871 00:33:09,150 --> 00:33:10,740 So OpenRewrite has transformations 872 00:33:10,740 --> 00:33:12,870 that'll let you upgrade those things 873 00:33:12,870 --> 00:33:15,540 very, very easily with just a click of a button. 874 00:33:15,540 --> 00:33:16,373 And on top of that, 875 00:33:16,373 --> 00:33:18,370 it also supports pull request generation. 876 00:33:19,380 --> 00:33:21,660 And this is an example of it, 877 00:33:21,660 --> 00:33:23,130 if you found the vulnerability in OSS, 878 00:33:23,130 --> 00:33:25,530 you can generate pull requests at scale 879 00:33:25,530 --> 00:33:26,670 using this technology. 880 00:33:26,670 --> 00:33:29,350 And so this is a quick video of 881 00:33:30,240 --> 00:33:32,850 when I wanted to fix temporary hijacking, 882 00:33:32,850 --> 00:33:34,000 what you're able to do, 883 00:33:34,892 --> 00:33:35,725 you can commit the chain. 884 00:33:35,725 --> 00:33:36,840 It lets you commit with forks. 885 00:33:36,840 --> 00:33:37,860 You can set the commit, 886 00:33:37,860 --> 00:33:38,970 the branch name, 887 00:33:38,970 --> 00:33:40,203 the commit title. 888 00:33:41,956 --> 00:33:44,940 It lets you create the pull request with gpg key signing. 889 00:33:44,940 --> 00:33:47,250 Yes, I know I'm pasting my gpg key into a Saas service, 890 00:33:47,250 --> 00:33:48,960 but it lets you generate your commits 891 00:33:48,960 --> 00:33:51,603 with gpg keys and then generates the pull requests. 892 00:33:54,796 --> 00:33:55,629 And this is the end result, right? 893 00:33:55,629 --> 00:33:57,213 Actually generating pull requests. 894 00:34:00,162 --> 00:34:04,216 But I said, Moderne indexes 7,000 repositories. 895 00:34:04,216 --> 00:34:05,760 So there are more than 7,000 OSS repositories 896 00:34:05,760 --> 00:34:07,045 in the world. 897 00:34:07,045 --> 00:34:08,483 How do we find the other projects? 898 00:34:10,124 --> 00:34:11,263 And so looping back to the beginning, 899 00:34:11,263 --> 00:34:12,465 CodeQL. 900 00:34:12,465 --> 00:34:13,757 So CodeQL, 901 00:34:15,419 --> 00:34:16,950 there's over 100.000 OSS projects that they index 902 00:34:16,950 --> 00:34:21,180 and over 35,000 OSS Java projects that are indexed. 903 00:34:21,180 --> 00:34:23,400 And so when you write a CodeQL query 904 00:34:23,400 --> 00:34:25,050 to find these vulnerabilities, 905 00:34:25,050 --> 00:34:25,883 you can get a list 906 00:34:25,883 --> 00:34:27,903 of all the vulnerable OSS projects. 907 00:34:29,292 --> 00:34:30,270 And then if you contribute that list 908 00:34:30,270 --> 00:34:35,040 to the Moderne Jenkins ingest repository 909 00:34:35,040 --> 00:34:36,153 to the CSV, 910 00:34:38,460 --> 00:34:40,230 they will ingest those repositories 911 00:34:40,230 --> 00:34:42,213 and let you run recipes against them. 912 00:34:43,170 --> 00:34:46,350 So finally, we've finally gotten there, 913 00:34:46,350 --> 00:34:48,200 let's go generate some pull requests. 914 00:34:52,232 --> 00:34:53,065 And so, here's the results 915 00:34:53,065 --> 00:34:54,450 of all the different campaigns of OSS 916 00:34:54,450 --> 00:34:56,024 pull request generation 917 00:34:56,024 --> 00:34:56,903 that I've been involved in. 918 00:34:59,610 --> 00:35:01,983 One of them actually was not directly mine. 919 00:35:03,136 --> 00:35:04,410 The rhostname array overflow 920 00:35:04,410 --> 00:35:07,290 was a project done by GitHub 921 00:35:07,290 --> 00:35:08,250 using my bot, 922 00:35:08,250 --> 00:35:10,320 my Python based bot. 923 00:35:10,320 --> 00:35:12,090 But yeah, for this past year, 924 00:35:12,090 --> 00:35:13,410 I've generated 64 pull requests 925 00:35:13,410 --> 00:35:14,730 for temporary directory hijacking 926 00:35:14,730 --> 00:35:16,290 partial pass traversals 32 927 00:35:16,290 --> 00:35:18,663 and zip slip, 100 pull requests. 928 00:35:20,160 --> 00:35:22,380 And for me, 929 00:35:22,380 --> 00:35:26,350 I've generated over 590 new pull requests 930 00:35:27,244 --> 00:35:28,590 in this year alone to fix various different vulnerabilities, 931 00:35:28,590 --> 00:35:30,570 new and or old projects. 932 00:35:30,570 --> 00:35:34,050 And personally I've generated over 5,200 pull requests 933 00:35:34,050 --> 00:35:36,950 across my history of being a software security researcher. 934 00:35:39,737 --> 00:35:41,805 (laughing) 935 00:35:41,805 --> 00:35:44,805 (audience clapping) 936 00:35:46,110 --> 00:35:46,943 Thank you. 937 00:35:48,540 --> 00:35:51,090 One unfortunate project 938 00:35:51,090 --> 00:35:52,950 of the three projects that I engaged in 939 00:35:52,950 --> 00:35:54,950 as a part of the Dan Kaminsky fellowship 940 00:35:55,944 --> 00:35:58,794 was the unfortunate recipient of all three pull requests. 941 00:36:00,750 --> 00:36:04,053 This is actually a project that's owned by Perforce. 942 00:36:04,920 --> 00:36:06,180 They didn't respond immediately 943 00:36:06,180 --> 00:36:08,304 when I opened the pull request. 944 00:36:08,304 --> 00:36:09,137 So I took to Twitter and said, 945 00:36:09,137 --> 00:36:09,970 Hey, by the way, 946 00:36:09,970 --> 00:36:11,243 I dropped an O-day on you, sorry. 947 00:36:12,396 --> 00:36:13,673 And they are now aware of it. 948 00:36:14,722 --> 00:36:16,680 (laughing) 949 00:36:16,680 --> 00:36:20,283 And so this is my contribution graph. 950 00:36:22,140 --> 00:36:23,640 Actually have an impact in OSS 951 00:36:24,930 --> 00:36:27,720 So I've talked about the technology, 952 00:36:27,720 --> 00:36:28,680 but now I wanna talk to you about 953 00:36:28,680 --> 00:36:31,980 some of the best practices for this technique. 954 00:36:31,980 --> 00:36:33,423 First off messaging, 955 00:36:34,440 --> 00:36:35,580 you're dealing with real people, 956 00:36:35,580 --> 00:36:37,430 you're dealing with real maintainers. 957 00:36:38,460 --> 00:36:40,200 There's this great saying 958 00:36:40,200 --> 00:36:42,720 All software problems are people problems in disguise. 959 00:36:42,720 --> 00:36:45,243 This is very true for this case. 960 00:36:46,311 --> 00:36:49,261 You're trying to fix these vulnerabilities with technology, 961 00:36:50,436 --> 00:36:51,269 but you dealing with a real person 962 00:36:51,269 --> 00:36:52,440 on the other end of this, 963 00:36:52,440 --> 00:36:53,880 which is receiving this pull request. 964 00:36:53,880 --> 00:36:55,980 And so you need to be kind, compassionate. 965 00:36:55,980 --> 00:36:57,080 You need to understand 966 00:36:59,032 --> 00:37:00,683 that you're potentially dropping an O-day on them. 967 00:37:02,004 --> 00:37:03,990 And maintainers are used to bug reports 968 00:37:03,990 --> 00:37:05,390 like that's been normalized, 969 00:37:07,206 --> 00:37:08,039 but when you're challenging them 970 00:37:08,039 --> 00:37:09,423 with a security vulnerability, 971 00:37:12,936 --> 00:37:13,980 sometimes ego gets involved a little bit 972 00:37:13,980 --> 00:37:15,905 and that's not a bad thing, 973 00:37:15,905 --> 00:37:16,770 but people are not normalized to, 974 00:37:16,770 --> 00:37:18,120 Hey, you've got a bug in your code, 975 00:37:18,120 --> 00:37:19,110 but not only is a bug, 976 00:37:19,110 --> 00:37:22,140 you can potentially put your users at risk because of it. 977 00:37:22,140 --> 00:37:23,910 So you need to be conscious of that in your messaging 978 00:37:23,910 --> 00:37:25,080 and detail of vulnerability 979 00:37:25,080 --> 00:37:26,680 and be compassionate when you're 980 00:37:27,668 --> 00:37:28,501 communicating with the maintainer. 981 00:37:28,501 --> 00:37:30,540 And so some shorter lessons, 982 00:37:30,540 --> 00:37:33,093 first one, sign off on all your commits. 983 00:37:34,380 --> 00:37:36,993 This is what a git- commit sign off looks like. 984 00:37:37,852 --> 00:37:39,002 And you might ask, why? 985 00:37:41,888 --> 00:37:44,400 And, there was a bunch of lawsuits in OSS 986 00:37:44,400 --> 00:37:46,503 TLDR, lawyers. 987 00:37:48,921 --> 00:37:50,310 So if you don't mind your pull requests rejected 988 00:37:50,310 --> 00:37:52,350 by evil dragon bureaucrats 989 00:37:52,350 --> 00:37:55,560 consider just commit sign 990 00:37:55,560 --> 00:37:56,510 and you'll be good. 991 00:37:57,510 --> 00:37:58,713 Be a good commitizen, 992 00:37:59,554 --> 00:38:01,080 gpg sign your commits. 993 00:38:01,080 --> 00:38:03,030 This is what commit signing looks like. 994 00:38:04,356 --> 00:38:05,310 And you won't end up getting impersonated 995 00:38:05,310 --> 00:38:07,044 like (indistinct) 996 00:38:07,044 --> 00:38:08,310 has multiple times on GitHub 997 00:38:10,404 --> 00:38:12,660 SECOM 998 00:38:12,660 --> 00:38:16,740 So SECOM is a standard for the commit message. 999 00:38:16,740 --> 00:38:18,490 I'm not gonna go into details on it 1000 00:38:19,348 --> 00:38:20,543 and it's not my talk to give, 1001 00:38:21,420 --> 00:38:23,370 but fundamentally it's a format for commit messages 1002 00:38:23,370 --> 00:38:24,720 that fix security vulnerabilities. 1003 00:38:24,720 --> 00:38:25,553 And if you follow this, 1004 00:38:25,553 --> 00:38:26,490 it just helps us 1005 00:38:26,490 --> 00:38:29,670 fall into a more normalized way of communicating 1006 00:38:29,670 --> 00:38:32,460 about vulnerabilities in the commit feed. 1007 00:38:32,460 --> 00:38:34,863 There are risks to using your GitHub account. 1008 00:38:35,760 --> 00:38:38,463 Is anybody here familiar with GitHub's angry unicorn? 1009 00:38:43,140 --> 00:38:45,303 This is my GitHub profile for most of 2020. 1010 00:38:46,680 --> 00:38:49,113 I broke my GitHub account by doing this. 1011 00:38:51,006 --> 00:38:51,839 So be warned. 1012 00:38:53,181 --> 00:38:54,180 However, I do recommend 1013 00:38:54,180 --> 00:38:55,880 using your personal GitHub account 1014 00:38:56,855 --> 00:38:57,688 because when maintainers 1015 00:38:57,688 --> 00:39:00,150 have questions, concerns, rants, 1016 00:39:00,150 --> 00:39:01,630 sometimes not often 1017 00:39:03,068 --> 00:39:05,196 you'd wanna be able to respond with 1018 00:39:05,196 --> 00:39:07,223 kindness and compassion and understanding, 1019 00:39:07,223 --> 00:39:09,204 and it'll make them understand 1020 00:39:09,204 --> 00:39:10,192 this is coming from a person 1021 00:39:10,192 --> 00:39:11,700 who cares about trying to fix vulnerabilities 1022 00:39:11,700 --> 00:39:13,650 and trying to improve their software, 1023 00:39:13,650 --> 00:39:16,110 but just can't do it in a way that's private 1024 00:39:16,110 --> 00:39:18,843 or the problem is too big to do this, 1025 00:39:20,512 --> 00:39:22,313 to report it to them one by one by one. 1026 00:39:24,324 --> 00:39:25,890 And then coordinate with GitHub 1027 00:39:25,890 --> 00:39:26,723 before attempting, 1028 00:39:26,723 --> 00:39:28,320 reach out to the GitHub security lab, 1029 00:39:28,320 --> 00:39:30,488 let them know you're gonna do this 1030 00:39:30,488 --> 00:39:31,328 because you don't wanna 1031 00:39:31,328 --> 00:39:32,520 get banned from GitHub. 1032 00:39:32,520 --> 00:39:33,353 Keep them in the loop. 1033 00:39:33,353 --> 00:39:34,552 They wanna know 1034 00:39:34,552 --> 00:39:36,090 they want to enable you. 1035 00:39:36,090 --> 00:39:36,923 They wanna support you. 1036 00:39:36,923 --> 00:39:37,970 That's what I've done. 1037 00:39:38,855 --> 00:39:40,110 I have a really good relationship with them. 1038 00:39:40,110 --> 00:39:41,610 So just keep them in the loop. 1039 00:39:42,996 --> 00:39:44,513 And then consider the implications. 1040 00:39:45,390 --> 00:39:47,010 I received this issue 1041 00:39:47,010 --> 00:39:49,290 shortly after engaging in this campaign, 1042 00:39:49,290 --> 00:39:51,570 one of my recent campaigns, 1043 00:39:51,570 --> 00:39:54,289 and I use the term, coordinated disclosure. 1044 00:39:54,289 --> 00:39:57,486 A lot of people still use responsible disclosure. 1045 00:39:57,486 --> 00:40:00,240 It's outdated term, but coordinated disclosure, 1046 00:40:00,240 --> 00:40:02,100 regardless of the term you use, 1047 00:40:02,100 --> 00:40:03,780 the answer is no, 1048 00:40:03,780 --> 00:40:06,051 this is not responsible disclosure. 1049 00:40:06,051 --> 00:40:07,080 This is not coordinated disclosure. 1050 00:40:07,080 --> 00:40:09,060 It's full disclosure of vulnerability. 1051 00:40:09,060 --> 00:40:11,250 If GitHub offered a way to create pull requests 1052 00:40:11,250 --> 00:40:12,510 that were private, 1053 00:40:12,510 --> 00:40:14,850 I would use it 100%. 1054 00:40:14,850 --> 00:40:16,000 I've asked them for it. 1055 00:40:19,176 --> 00:40:21,540 So you need to be considerate of that. 1056 00:40:21,540 --> 00:40:23,760 You're dropping an O-day on a maintainer 1057 00:40:23,760 --> 00:40:25,500 and you're gonna add stress in their life 1058 00:40:25,500 --> 00:40:27,570 that they didn't have before. 1059 00:40:27,570 --> 00:40:29,970 And now they've gotta deal with what you've given them. 1060 00:40:29,970 --> 00:40:31,830 So just keep that in mind. 1061 00:40:31,830 --> 00:40:33,510 But I argue that 1062 00:40:33,510 --> 00:40:36,703 at the scale at which the vulnerabilities we have, 1063 00:40:36,703 --> 00:40:40,530 the risks and the downsides 1064 00:40:40,530 --> 00:40:45,000 outweigh the potential negative consequences 1065 00:40:45,000 --> 00:40:46,723 of dropping an O- day 1066 00:40:46,723 --> 00:40:47,670 because of the amount of good we can have 1067 00:40:47,670 --> 00:40:49,720 by fixing these vulnerabilities at scale. 1068 00:40:51,835 --> 00:40:55,053 So in conclusion, as security researchers, 1069 00:40:57,295 --> 00:40:58,943 I believe we have an obligation to society. 1070 00:41:00,060 --> 00:41:03,010 We are the ones that know that these vulnerabilities exist. 1071 00:41:03,971 --> 00:41:06,180 We've seen them in pentest reports. 1072 00:41:06,180 --> 00:41:07,620 We've written them about them. 1073 00:41:07,620 --> 00:41:09,240 We've seen them in code reviews 1074 00:41:09,240 --> 00:41:10,200 that come up again and again, 1075 00:41:10,200 --> 00:41:11,430 but we are the ones that know 1076 00:41:11,430 --> 00:41:13,440 that these vulnerabilities exist 1077 00:41:13,440 --> 00:41:15,720 and we know what to fix them. 1078 00:41:15,720 --> 00:41:18,960 Unfortunately, a lot of developers out there 1079 00:41:18,960 --> 00:41:19,830 surprise, surprise, 1080 00:41:19,830 --> 00:41:22,023 don't watch D3FCON or Black Hat talks. 1081 00:41:25,167 --> 00:41:29,100 So we need to be able to help the community where we can 1082 00:41:29,100 --> 00:41:30,720 and contribute back. 1083 00:41:30,720 --> 00:41:31,650 There's a problem. 1084 00:41:31,650 --> 00:41:35,040 GitHub estimates that for every 500 developers, 1085 00:41:35,040 --> 00:41:36,603 you've one security researcher. 1086 00:41:37,470 --> 00:41:39,183 The odds are stacked against us, 1087 00:41:40,710 --> 00:41:43,080 but I believe that with this technique 1088 00:41:43,080 --> 00:41:45,153 and with deploying this, 1089 00:41:46,815 --> 00:41:48,780 we can fix vulnerabilities at scale. 1090 00:41:48,780 --> 00:41:49,950 And I believe this is the best way 1091 00:41:49,950 --> 00:41:52,210 to fix vulnerabilities at scale across OSS 1092 00:41:54,163 --> 00:41:57,060 and imagine deploying this technology, for example, 1093 00:41:57,060 --> 00:41:59,110 to eliminate ES SQL injection across OSS 1094 00:42:01,303 --> 00:42:02,136 or if when Open Rewrite supports 1095 00:42:02,136 --> 00:42:03,210 C and C++. 1096 00:42:03,210 --> 00:42:04,080 We could eliminate 1097 00:42:04,080 --> 00:42:07,230 entire classes of memory corruption bugs, 1098 00:42:07,230 --> 00:42:10,200 simply by generating 10s, 100s of pull requests 1099 00:42:10,200 --> 00:42:12,420 across OSS, right? 1100 00:42:12,420 --> 00:42:13,350 Just gone. 1101 00:42:13,350 --> 00:42:14,550 We've dealt with that vulnerability. 1102 00:42:14,550 --> 00:42:16,673 Let's move on to something more interesting. 1103 00:42:18,690 --> 00:42:20,790 So I wanna leave you with one final quote. 1104 00:42:21,900 --> 00:42:23,580 It's from Dan Kaminsky, 1105 00:42:23,580 --> 00:42:25,280 it's on his Twitter profile today. 1106 00:42:27,810 --> 00:42:29,340 We can fix it. 1107 00:42:29,340 --> 00:42:31,170 We have the technology. 1108 00:42:31,170 --> 00:42:33,330 Okay, we need to create the technology. 1109 00:42:33,330 --> 00:42:34,429 All right, 1110 00:42:34,429 --> 00:42:36,600 the policy guys are mucking with the technology. 1111 00:42:36,600 --> 00:42:37,593 Relax. 1112 00:42:38,430 --> 00:42:39,263 We're on it. 1113 00:42:42,627 --> 00:42:45,794 (audience applauding) 1114 00:42:53,427 --> 00:42:54,260 Thank you. 1115 00:42:54,260 --> 00:42:55,450 Couple of little sound bites, 1116 00:42:56,340 --> 00:42:57,720 learn CodeQL. 1117 00:42:57,720 --> 00:43:00,750 Seriously, it's an incredibly powerful language. 1118 00:43:00,750 --> 00:43:02,000 Contribute to OpenRewrite 1119 00:43:04,120 --> 00:43:07,463 and CodeQL and you can deploy your security fixes at scale. 1120 00:43:08,340 --> 00:43:10,260 And then if you wanna chat more with me, 1121 00:43:10,260 --> 00:43:13,050 my Twitter DMs are open, 1122 00:43:13,050 --> 00:43:15,210 join the GitHub security lab, Slack channel, 1123 00:43:15,210 --> 00:43:16,953 and the OpenRewrite slack channel. 1124 00:43:17,982 --> 00:43:18,900 And if you wanna discuss the wider problem, 1125 00:43:18,900 --> 00:43:19,733 it's not on the slide, 1126 00:43:19,733 --> 00:43:21,090 but if you wanna discuss the wider problem 1127 00:43:21,090 --> 00:43:23,463 of OSS security vulnerabilities in general, 1128 00:43:24,777 --> 00:43:25,980 there is the Linux foundation's OSS 1129 00:43:25,980 --> 00:43:27,420 security foundation, 1130 00:43:27,420 --> 00:43:29,190 where they're having weekly meetings, 1131 00:43:29,190 --> 00:43:31,210 discussing the critical vulnerabilities 1132 00:43:32,621 --> 00:43:34,763 and issues impacting OSS and securing those things. 1133 00:43:35,743 --> 00:43:36,690 So if you're looking for something, 1134 00:43:36,690 --> 00:43:37,710 a place to get involved, 1135 00:43:37,710 --> 00:43:39,000 and it's not directly involved with this, 1136 00:43:39,000 --> 00:43:41,100 but you wanna get involved with OSS security. 1137 00:43:41,100 --> 00:43:43,320 That's a great channel to get involved in and learn more 1138 00:43:43,320 --> 00:43:44,940 about this topic. 1139 00:43:44,940 --> 00:43:46,260 And I wanna leave a final thanks to 1140 00:43:46,260 --> 00:43:48,990 HUMAN, my sponsor, 1141 00:43:48,990 --> 00:43:50,880 and the Dan Kaminsky fellowship sponsor 1142 00:43:50,880 --> 00:43:52,767 that enabled me to do this. 1143 00:43:52,767 --> 00:43:54,450 Moderne who has been an awesome companion 1144 00:43:54,450 --> 00:43:56,640 and team to work with. 1145 00:43:56,640 --> 00:44:00,299 Lidia Juliano for being the Black Hat speaker coach, 1146 00:44:00,299 --> 00:44:02,370 to make this talk what it was. 1147 00:44:02,370 --> 00:44:03,843 And Shyam, my intern, 1148 00:44:06,087 --> 00:44:07,170 he did some of the graphics 1149 00:44:08,739 --> 00:44:10,440 and without control flow analysis 1150 00:44:10,440 --> 00:44:12,480 would not have come together. 1151 00:44:12,480 --> 00:44:13,770 So thank you. 1152 00:44:13,770 --> 00:44:14,603 Yes. 1153 00:44:14,603 --> 00:44:16,259 Thank you all for coming. 1154 00:44:16,259 --> 00:44:19,295 (audience clapping) 1155 00:44:19,295 --> 00:44:20,128 (upbeat music)