1 00:00:14,120 --> 00:00:17,000 Hey, thanks again for joining us here in the AppSec Village. 2 00:00:17,000 --> 00:00:21,220 Good morning, good evening, good afternoon, or good night, depending on where you're at in the world. 3 00:00:21,220 --> 00:00:25,180 Kind of a little hard to tell right now since we're not all in one big room together. 4 00:00:25,180 --> 00:00:28,220 But, I've got another exciting talk for you. 5 00:00:28,380 --> 00:00:33,020 The next talk in our agenda is going to be API and Security Top 10. 6 00:00:33,080 --> 00:00:35,600 A guided tour to the wild, wild world. 7 00:00:35,600 --> 00:00:37,160 We've got two speakers this time. 8 00:00:37,160 --> 00:00:39,860 We've got David Sopas and Paulo Silva. 9 00:00:39,860 --> 00:00:45,560 David leads a team of security researchers at Checkmarks and is a co-founder of Char49. 10 00:00:45,660 --> 00:00:54,700 With more than 15 years of experience in pin testing and vulnerability research, he has been acknowledged by companies like Google, Yahoo, eBay, and Microsoft. 11 00:00:54,860 --> 00:01:03,480 After retiring from his bug bounty hunting career, David now focuses on the Internet of Things security and tries to learn new things each and every day. 12 00:01:04,100 --> 00:01:12,760 Paulo, since his first OWASP local event back in 2010, has been active in the community, contributing to several OWASP projects. 13 00:01:12,760 --> 00:01:24,540 With over 15 years of professional experience as a software developer, he is now focused on ethical hacking and security research with regular collaborations with companies like Char49 and Checkmarks. 14 00:01:24,540 --> 00:01:30,930 He's interested in programming languages, DevSecOps, and web mobile secure coding practices. 15 00:01:31,180 --> 00:01:34,620 Please welcome David and Paulo. 16 00:01:36,060 --> 00:01:43,480 Hello everyone and welcome to the API and Security Top 10, the guided tour to the wild wild world. 17 00:01:43,580 --> 00:01:58,320 Before we start, I would like to thank and appreciate the opportunity to be at DEF CON, even if it's in safe mode, and AppSecVillage for approving our research. 18 00:01:58,320 --> 00:01:59,860 So, thank you. 19 00:02:00,160 --> 00:02:02,000 Let's start. 20 00:02:02,000 --> 00:02:18,620 Well, I will start by presenting who we are, with a brief description of what APIs are, the importance in today's software, the differences from traditional apps. 21 00:02:18,620 --> 00:02:40,160 Then we went through the OWASP API Security Top 10, talked a little bit about the project and our contribution to that project, and then guns blazing on the API's wild wild world, where we show real vulnerabilities on modern web applications and describe a little bit about our findings. 22 00:02:41,740 --> 00:02:43,300 Who we are. 23 00:02:43,300 --> 00:02:45,280 Well, my name is David Sopas. 24 00:02:45,280 --> 00:02:49,360 I work for Checkmarks since February 16. 25 00:02:49,780 --> 00:02:56,820 I'm currently the security team leader of a very talented group of researchers. 26 00:02:56,820 --> 00:03:03,000 I'm chief operating officer and co-founder of Shard49. 27 00:03:03,000 --> 00:03:08,240 I was a bug bounty hunter a few times ago. 28 00:03:08,860 --> 00:03:17,040 I have around 15 years in penetration testing and security research. 29 00:03:17,600 --> 00:03:31,740 Nowadays, I'm playing more with breaking IoT devices, specifically using BLE technology, and focusing on modern web applications, of course, and API. 30 00:03:32,540 --> 00:03:39,880 Some of my work you can already see on TechCrunch, The Register, Security Week, and ThreatPost. 31 00:03:40,100 --> 00:03:44,300 Sorry about the photo, but I used the pandemic filter. 32 00:03:44,840 --> 00:03:51,200 It was during the quarantine in Portugal, so that's it. 33 00:03:51,200 --> 00:03:53,700 I think it was very appropriate to this event. 34 00:03:53,700 --> 00:03:54,920 Moving on to Paulo. 35 00:03:55,620 --> 00:03:57,440 Hello, and thanks for watching. 36 00:03:57,440 --> 00:04:03,520 My name is Paulo Silva, and it's a great pleasure to be presenting at DEF CON, especially together with my friend David. 37 00:04:03,820 --> 00:04:14,700 I used to define myself as a freedom enthusiast, since I love everything related to free and open-source software, World Wide Web, or cross-countering and bikepacking. 38 00:04:14,860 --> 00:04:21,740 I have more than 15 years as a software developer, so I know what is plenty of time to have done all sorts of mistakes. 39 00:04:22,100 --> 00:04:28,860 Right now, I do ethical hacking and security research, and since 2010, I'm a regular OWASP volunteer. 40 00:04:30,520 --> 00:04:39,820 Currently, I'm the OWASP Go Secure Coding Practices project co-leader, and main collaborator on OWASP API security project. 41 00:04:40,000 --> 00:04:45,040 Meanwhile, I'm used to fill the gap and deliver security awareness sessions in academia. 42 00:04:46,800 --> 00:04:51,040 Before continuing, the mandatory disclaimer. 43 00:04:51,040 --> 00:04:59,320 Hacking systems without permission is crime, and we are not responsible for misuse of any information we are about to disclose. 44 00:05:00,220 --> 00:05:03,340 Let's talk a bit about APIs. 45 00:05:03,700 --> 00:05:09,420 I like to look for definitions in the dictionary, because words matter. 46 00:05:09,420 --> 00:05:16,040 Nevertheless, I'm not expecting to find a definition for API in the dictionary. 47 00:05:16,600 --> 00:05:23,680 But something interesting about interface, defined as a common boundary of two bodies. 48 00:05:23,680 --> 00:05:31,260 In fact, you can think about APIs this way, a common language that connected things talk in order to get work done. 49 00:05:33,060 --> 00:05:36,480 APIs have a central role in today's software. 50 00:05:36,480 --> 00:05:41,200 They are the common ground among several types of devices and applications. 51 00:05:41,200 --> 00:05:47,840 A generic language that all them know how to talk, to exchange data and execute functions. 52 00:05:48,280 --> 00:05:52,600 This is different from traditional web applications in many ways. 53 00:05:52,600 --> 00:05:58,400 Before, we had web servers playing this central role, doing the heavy work. 54 00:05:58,400 --> 00:06:10,640 Answering client requests, gathering data from databases and other web services, gluing everything together, computing the final HTML and returning it back to the client to be rendered. 55 00:06:12,040 --> 00:06:16,080 Nowadays, there are several types of clients behind web browsers. 56 00:06:16,080 --> 00:06:22,240 We have smart bulbs, wearables, cars, surveillance cameras, etc, etc, etc. 57 00:06:22,400 --> 00:06:32,100 All these clients use APIs to make their capabilities available to other clients and to communicate with each other. 58 00:06:32,100 --> 00:06:35,480 Clients are now more powerful than they were before. 59 00:06:35,480 --> 00:06:41,100 In modern web applications, there is a clear separation between front-end and back-end. 60 00:06:41,100 --> 00:06:57,080 The front-end nowadays is a bunch of JavaScript and CSS providing rich user interfaces to collect data, send the data to several APIs, making it generally available to all clients regardless their type. 61 00:06:57,080 --> 00:07:07,900 I think this is pretty much about APIs and we should move on to the OWASP API top 10 with David. 62 00:07:07,900 --> 00:07:11,420 So, OWASP API security top 10. 63 00:07:12,360 --> 00:07:15,860 You may have already heard about OWASP. 64 00:07:15,860 --> 00:07:23,280 In its own words, it is a non-profit foundation that works to improve the security of software. 65 00:07:23,280 --> 00:07:28,960 OWASP top 10 is one of the flagship projects and most of you should already know it already. 66 00:07:28,960 --> 00:07:38,040 It has played an enormous role to bring security awareness into organizations, both to management and dev teams. 67 00:07:38,040 --> 00:07:43,260 But we have seen very specific API related issues popping up. 68 00:07:43,260 --> 00:07:46,020 We should learn from past mistakes and R. 69 00:07:46,020 --> 00:07:55,080 Zialon and Inon Skedi decided to start the OWASP API security project to address API specific issues. 70 00:07:55,080 --> 00:08:04,400 The document follows the same approach and popular OWASP top 10 for readability purposes, but it's 100% API oriented. 71 00:08:05,980 --> 00:08:07,840 Our contribute. 72 00:08:08,120 --> 00:08:18,520 Vendors have been doing business as usual and there is no API specific data for a public call for data like other OWASP projects. 73 00:08:18,520 --> 00:08:20,320 So we had to research. 74 00:08:20,320 --> 00:08:39,060 There are several bug bounty programs that released full disclosure write-ups and we went there and even on some public information that we got hands-on, but we had to review it and pick only the API related issues. 75 00:08:39,060 --> 00:08:46,740 So while reviewing the reports and the write-ups, we start standardizing the categorization and grouping things together. 76 00:08:46,740 --> 00:08:52,680 After a few months, we were able to compute a statistical top 10. 77 00:08:52,680 --> 00:09:00,620 Security risk, of course, was using the OWASP risk rating methodology. 78 00:09:00,660 --> 00:09:14,020 We drafted the first OWASP API security top 10 and asked several entities, organizations and individuals with relevant AppSec experience in the API field, at least to get us some feedback. 79 00:09:14,020 --> 00:09:25,280 The draft was published on GitHub and during the several months we worked with AppSec community to get some feedback and change a little things. 80 00:09:25,280 --> 00:09:32,960 By the end of 2019, the final version was published and we were very happy with it. 81 00:09:32,960 --> 00:09:40,480 Then we went wild to validate how accurate the OWASP API security top 10 2019 was. 82 00:09:40,480 --> 00:09:46,620 I hope you can have the opportunity to download it and see it. 83 00:09:47,880 --> 00:09:50,560 APIs in the wild, wild world. 84 00:09:51,220 --> 00:09:52,360 Our research. 85 00:09:53,960 --> 00:10:03,440 Our focus was only on high-profile web applications and, of course, focusing on the API. 86 00:10:03,440 --> 00:10:12,680 We want to map all the vulnerabilities that we found on the OWASP top 10 2019. 87 00:10:13,260 --> 00:10:22,540 So, you may ask what was our biggest problem, if I can say that. 88 00:10:23,220 --> 00:10:33,380 And, yeah, it was the responsible disclosure because many companies didn't reply or just didn't care about security. 89 00:10:33,380 --> 00:10:39,680 That was the most challenging issue that we encountered. 90 00:10:40,340 --> 00:10:44,900 On our research, we tested 8 APIs. 91 00:10:44,900 --> 00:10:54,980 We discovered 28 API issues that we categorized as you can see on the right table. 92 00:10:54,980 --> 00:11:01,880 We got a minimum CVSS 2.7 and a 7.7 max. 93 00:11:02,880 --> 00:11:07,380 We found 7 broken user authentication. 94 00:11:07,520 --> 00:11:20,220 With 5 issues, we have broken object level authorization or BOLA and also with 5 excessive data exposure. 95 00:11:20,480 --> 00:11:23,660 Security misconfiguration was 4. 96 00:11:23,660 --> 00:11:26,780 Broken function level authorization, 3. 97 00:11:26,780 --> 00:11:31,240 And also with 3, lack of resources and rate limiting, 3. 98 00:11:31,240 --> 00:11:36,380 Finishing with 1 result on injection, not so common anymore. 99 00:11:38,180 --> 00:11:39,620 Findings. 100 00:11:39,640 --> 00:11:41,440 Moving on to Paolo. 101 00:11:45,440 --> 00:11:49,620 Okay, let's start with the broken object level authorization. 102 00:11:49,620 --> 00:11:54,360 You may know this by IDOR or Insecure Direct Object Reference. 103 00:11:54,360 --> 00:12:01,880 But while writing OWASP API security top 10, we decided to rename it since IDOR is not a very accurate name. 104 00:12:02,640 --> 00:12:09,940 In this case, we found 2 exposed APIs, a GraphQL and a REST one. 105 00:12:09,940 --> 00:12:13,780 Both vulnerable to broken object level authorization. 106 00:12:14,660 --> 00:12:22,080 As you may know, GraphQL is not like REST and you should ask for what you need and you will get exactly that. 107 00:12:22,080 --> 00:12:24,180 Nothing more, nothing less. 108 00:12:24,280 --> 00:12:30,160 This is valid for resources like profile but also to their fields. 109 00:12:30,160 --> 00:12:34,560 Of course, we can try to guess everything or use word lists. 110 00:12:34,560 --> 00:12:44,480 But it becomes even more interesting if you find another vulnerability like a security misconfiguration allowing you to query that information. 111 00:12:44,560 --> 00:12:52,200 More details about the security misconfiguration specific to GraphQL and its specific section. 112 00:12:52,200 --> 00:12:56,840 You just have to wait a few more issues and we will get there. 113 00:12:57,500 --> 00:13:01,400 By now, let's focus on the requests on the left side. 114 00:13:01,400 --> 00:13:06,120 We are looking for a specific profile based on its slug. 115 00:13:06,120 --> 00:13:12,110 The slug is public information since it's part of the user's public URL. 116 00:13:12,380 --> 00:13:15,920 On the right side, we have the API response. 117 00:13:15,920 --> 00:13:27,200 We can see user's public URL, the slug and also something that points the profile to be private. 118 00:13:27,200 --> 00:13:30,420 But nowadays, we never know what private means. 119 00:13:30,520 --> 00:13:40,000 We have several other properties but there's another one, the ID, which we will use with the REST API. 120 00:13:41,000 --> 00:13:53,400 We took the ID property we got from the GraphQL API and we used it to request a user on the REST API. 121 00:13:53,400 --> 00:14:02,040 We got additional information including billing information with full address and tax ID number. 122 00:14:02,640 --> 00:14:09,020 At least this time, API doesn't say that the user resource is private. 123 00:14:09,020 --> 00:14:12,660 But note that both requests were anonymous. 124 00:14:12,660 --> 00:14:15,640 There was no authentication nor authorization. 125 00:14:16,040 --> 00:14:18,860 I think this was a good warm-up. 126 00:14:18,860 --> 00:14:21,460 We can continue with David. 127 00:14:23,740 --> 00:14:25,420 Broken user authentication. 128 00:14:25,420 --> 00:14:28,520 In this case, SoundCloud. 129 00:14:28,520 --> 00:14:33,920 Our final objective was to get account takeover and we did it. 130 00:14:33,920 --> 00:14:43,600 On SoundCloud, which is already disclosed this issue, I can give you a brief description of what we did. 131 00:14:43,600 --> 00:14:52,760 On user account lockout, based on failed login attempt, is something that we don't see often. 132 00:14:52,760 --> 00:15:00,540 In this case, the API was rate-limited. 133 00:15:00,540 --> 00:15:05,040 So, nevertheless, it was possible to bypass and we will show you how. 134 00:15:05,540 --> 00:15:15,860 So, chaining the rate-limited bypass with the user enumeration issue that we found, we were able to accomplish the account takeover via credential stuffing attack. 135 00:15:17,700 --> 00:15:25,200 This is a typical user enumeration scenario where we abuse the recover password mechanism. 136 00:15:25,200 --> 00:15:34,100 We have a binary feedback depending either the provided email belongs to a user account or not, as you can see on the perp screenshot. 137 00:15:36,100 --> 00:15:41,940 Rate-limiting bypass was something fun, because at least it was the first time we saw it. 138 00:15:41,940 --> 00:15:47,760 It was based on the user agent, the device ID and the signature. 139 00:15:47,760 --> 00:15:52,220 So, both device ID and signature was computed client-side. 140 00:15:52,520 --> 00:16:02,240 Instead of reversing the JavaScript logic, we gathered three different combinations to be randomly picked by our brute-force script. 141 00:16:02,240 --> 00:16:11,540 After a first fixed attempt, we will also use different EIPs by using Tor, forcing different as-it-nodes. 142 00:16:12,000 --> 00:16:28,480 Rate-limiting is very important, of course, and it should be very restrictive for authentication endpoints, but it can also not be enough to prevent what the user account lockout does, which should be implemented both authentication and rate-limited. 143 00:16:29,420 --> 00:16:36,620 So, this is the example that we did with a single-threaded POC running in an ordinary laptop. 144 00:16:36,620 --> 00:16:45,180 For sure, if we use concurrency or parallelism and cloud-based approach, we have done it much faster, for sure. 145 00:16:46,980 --> 00:16:56,600 So, in the end, this is the access token we can have and the account takeover is completed to follow. 146 00:17:03,290 --> 00:17:06,750 Let's talk about excessive data exposure. 147 00:17:06,770 --> 00:17:10,670 This is probably one of my favorite findings. 148 00:17:11,570 --> 00:17:22,190 We started with the user enumeration issue on the recovery password mechanism and later a security misconfiguration allowing us to leverage the attack. 149 00:17:22,590 --> 00:17:37,130 The recovery password required the user to provide its email address on the front-end, which then issues an API request to retrieve a list of available delivery channels, either email or phone. 150 00:17:37,130 --> 00:17:45,850 The user can pick one on the front-end and then a one-time password is delivered so that it can recover his password. 151 00:17:45,850 --> 00:17:55,270 In this workflow, we noticed that a URL, including a JSON web token, were provided for each delivery method. 152 00:17:55,270 --> 00:18:00,410 So, we took the phone URL and decoded the JSON web token. 153 00:18:00,830 --> 00:18:14,470 Then we found that the actual user phone number is included in the JSON web token payload section, meaning that we can exchange user emails by phone numbers. 154 00:18:14,810 --> 00:18:21,810 Note that these API requests are anonymous, since they are aimed to recover passwords. 155 00:18:21,810 --> 00:18:31,110 We decided to go further and do this for an arbitrary list of email addresses that we gathered from pastebin.com. 156 00:18:31,110 --> 00:18:39,970 It had 169 email addresses and we got 7 user accounts with email and phone number. 157 00:18:40,690 --> 00:18:44,570 Meanwhile, we found a security misconfiguration. 158 00:18:44,570 --> 00:18:57,550 In fact, we found an exposed error log file, including some sensitive information, but the most interesting one was the location of some internal files. 159 00:18:57,750 --> 00:19:04,230 Luckily, these files were also exposed and publicly accessible. 160 00:19:04,230 --> 00:19:07,330 And this is how some of them look like. 161 00:19:07,330 --> 00:19:18,190 They were mailing reports with valid user account emails and also the mailing subject. 162 00:19:18,190 --> 00:19:25,790 So, just by themselves, they were good enough to be used for a phishing campaign. 163 00:19:25,790 --> 00:19:34,410 But we could even enrich it with phone numbers, complete the info and drive some phishing or smishing attack. 164 00:19:38,280 --> 00:19:42,360 APIs tend to handle huge amounts of data. 165 00:19:42,360 --> 00:19:46,000 And some of them also leak part of that data. 166 00:19:46,000 --> 00:19:48,480 You may know Meetup. 167 00:19:48,480 --> 00:19:57,500 Meetup offers pro accounts, which give you access to unlimited groups and targeted communications to members. 168 00:19:57,500 --> 00:20:03,940 You get several other features, all of them for $30 per month per group. 169 00:20:04,440 --> 00:20:08,280 And, in fact, you also get access to free email addresses. 170 00:20:09,040 --> 00:20:27,260 Regardless of what privacy settings you choose and what Meetup says, that they won't give your email address to anyone, what we saw is that as long as you can issue an API request, you will be able to retrieve email addresses from the API. 171 00:20:27,860 --> 00:20:38,960 And we did this for 38,504 user profiles just on the WordPress network. 172 00:20:39,380 --> 00:20:42,760 I think it's quite huge. 173 00:20:42,760 --> 00:20:47,560 Let's continue with David with lack of resources and rate limiting. 174 00:20:48,740 --> 00:20:56,700 Well, with lack of resources and rate limiting, the final objective was user enumeration. 175 00:20:56,700 --> 00:21:01,820 So, what we have is improper rate limiting. 176 00:21:02,300 --> 00:21:07,520 And, in the end, we got the user enumeration. 177 00:21:07,520 --> 00:21:10,540 In this screenshot you can see it. 178 00:21:10,540 --> 00:21:18,440 Because, to be fair, the Meetup, which is the target, had the rate limiting defined on... 179 00:21:18,440 --> 00:21:20,700 It followed the best practice. 180 00:21:20,700 --> 00:21:26,460 You can see the X rate limit custom response header. 181 00:21:26,460 --> 00:21:33,660 But, when we tried to enumerate members, we noticed that something was strange. 182 00:21:34,440 --> 00:21:41,620 We noticed that after a few rate-limited requests, it just got stuck. 183 00:21:41,620 --> 00:21:48,300 So, I don't know if it was a bug on the server side or something like that. 184 00:21:48,300 --> 00:21:56,780 Because it allowed us to continue and did not lock our attempt to enumerate. 185 00:21:57,060 --> 00:22:00,840 Just a small preview, nothing fancy. 186 00:22:00,840 --> 00:22:15,980 But, you can see that, in the end, after a few requests, we did find a lot of user names that we could use. 187 00:22:19,860 --> 00:22:27,240 Ok, so, just simple enumeration, including the username, user location, the profile photo... 188 00:22:27,860 --> 00:22:33,140 And, by the way, you can see on the bio that it's the co-founder and former CTO. 189 00:22:34,560 --> 00:22:38,860 Of Meetup and PM on Facebook. 190 00:22:38,860 --> 00:22:41,400 So , it was... well, it was the number 2. 191 00:22:41,400 --> 00:22:50,680 So, I'm supposing the idea was very close to be the founder or something very important on the Meetup. 192 00:22:50,680 --> 00:22:54,140 But, just to show you that a simple... 193 00:22:54,920 --> 00:23:01,140 If you don't control and test the rate-limited protection... 194 00:23:03,140 --> 00:23:05,400 You need to make serious. 195 00:23:05,400 --> 00:23:06,640 You better test it. 196 00:23:06,640 --> 00:23:12,220 It's not just put a header and didn't test it and forget it. 197 00:23:12,220 --> 00:23:14,660 You need to control it, ok? 198 00:23:14,660 --> 00:23:16,180 So, to follow. 199 00:23:24,480 --> 00:23:30,320 Let's talk about the second authorization issue in the OWASP API security top 10. 200 00:23:30,380 --> 00:23:32,660 Broken function level authorization. 201 00:23:32,840 --> 00:23:35,600 We began with broken object level authorization. 202 00:23:35,600 --> 00:23:38,000 And you should expect something similar. 203 00:23:38,000 --> 00:23:45,100 But instead of requesting objects by their unique identifier, we're gonna ask APIs to execute functions. 204 00:23:45,100 --> 00:23:48,240 Either regular user or admin ones. 205 00:23:48,720 --> 00:23:55,480 We're glad you stick with us until here because we didn't have the chance to talk about COVID-19 pandemic yet. 206 00:23:55,520 --> 00:24:02,100 This pandemic, among other severe consequences, also created a new battleground. 207 00:24:02,100 --> 00:24:04,860 Conferencing tools and services. 208 00:24:04,860 --> 00:24:11,640 By the way, this finding was yet another great job by our friends João Moraes and Guilhom Lopes. 209 00:24:11,980 --> 00:24:18,180 João Moraes is also presenting at DEF CON this year together with Pedro Umblino, another friend of us. 210 00:24:18,180 --> 00:24:22,220 And you should not lose the chance to watch their talk. 211 00:24:23,660 --> 00:24:30,300 In addition to the audio and video features, this conferencing tool also offers a user chat. 212 00:24:30,300 --> 00:24:37,920 I think they know that users need a way to ask others whether they can hear them. 213 00:24:38,180 --> 00:24:43,160 I'm not sure whether this is foolproof, but let's see what we found. 214 00:24:45,020 --> 00:24:49,940 While joining the meeting, we noticed an API request like the one on the left. 215 00:24:49,940 --> 00:24:53,520 The response on the right returns a list of participants. 216 00:24:54,380 --> 00:25:03,840 We don't know what the ticket code is, but when we see a numeric identifier like the viewer code ID, we surely test it. 217 00:25:04,380 --> 00:25:19,440 So, simply iterating over viewer code ID, we got exactly 1496 email addresses from other meeting participants. 218 00:25:19,440 --> 00:25:26,720 And we also got 673 phone numbers from the same participants. 219 00:25:28,320 --> 00:25:31,660 Let's discuss security misconfigurations with David. 220 00:25:34,530 --> 00:25:36,570 Security misconfiguration... 221 00:25:38,210 --> 00:25:46,730 Well, with security misconfiguration we did found a couple of things, but please don't expect too much from here. 222 00:25:46,730 --> 00:25:49,170 It's really a bunch of nothing. 223 00:25:49,170 --> 00:25:59,990 We did found stack traces and one of them, not related to the stack trace, one of the security misconfiguration was a GraphQL introspection. 224 00:26:00,370 --> 00:26:10,950 It was a little bit... I think it was one of the first time that I saw it in production, but let's see it in detail. 225 00:26:10,950 --> 00:26:15,990 Okay, so stack trace on an handled Java exception. 226 00:26:15,990 --> 00:26:21,200 So, this type of vulnerability is like boring, moving along. 227 00:26:21,590 --> 00:26:25,030 Another stack trace, but this time with more style. 228 00:26:25,030 --> 00:26:27,220 It's Node.js, an handled exception. 229 00:26:27,870 --> 00:26:31,710 Well, at least it's clean up your own mess, right? 230 00:26:33,330 --> 00:26:36,950 Okay, finally, something more clean. 231 00:26:36,950 --> 00:26:41,990 You know that development tools should not be deployed in production, right? 232 00:26:43,790 --> 00:26:49,270 And yes, this is the GraphQL introspection attack. 233 00:26:50,170 --> 00:26:57,190 And please, GraphQL introspection should be disabled in production, like I said before. 234 00:26:57,190 --> 00:27:05,910 This will give the attacker the opportunity to get the structure of your database and many more information. 235 00:27:05,910 --> 00:27:10,090 So , devs, keep that in mind. 236 00:27:10,150 --> 00:27:16,950 Also, unique ID is Base64 obfuscated. 237 00:27:16,950 --> 00:27:22,530 This is what we underlined on the Burp screenshot. 238 00:27:22,530 --> 00:27:27,170 By the way, Base64 is encoding and not obfuscated. 239 00:27:27,190 --> 00:27:31,230 But anyway, thanks for the detailed explanation. 240 00:27:32,050 --> 00:27:38,290 Injection, one of my favorite sections of this presentation. 241 00:27:38,610 --> 00:27:40,070 And guess what? 242 00:27:40,950 --> 00:27:47,610 We changed the vulnerabilities with cross-site scripting and cross-site request forgery. 243 00:27:47,610 --> 00:27:57,070 And in the end, well, we have the cool scenarios to present. 244 00:27:57,470 --> 00:27:58,690 Guess what? 245 00:27:58,690 --> 00:27:59,710 Meetup. 246 00:27:59,790 --> 00:28:02,070 All your meetup belong to us. 247 00:28:02,730 --> 00:28:05,050 What was the real objective? 248 00:28:05,050 --> 00:28:07,670 Well, I used meetup. 249 00:28:07,670 --> 00:28:21,710 And when I see a discussion part where you could post some comments and messages to the group itself, it immediately wanted me to pop up some alert box. 250 00:28:21,710 --> 00:28:32,050 And coming from a guy that loves and keeps studying cross-site scripting attacks, it was something that I would like to do. 251 00:28:33,370 --> 00:28:39,750 The frontend immediately won't allow it and sanitized most of the content that I posted. 252 00:28:39,750 --> 00:28:49,810 So, after a while and checking the burp proxy logs, I noticed that some requests were being made to the API. 253 00:28:49,810 --> 00:28:52,010 So, API did the job. 254 00:28:52,930 --> 00:28:58,790 I did found a payload that immediately triggered what I wanted. 255 00:28:58,790 --> 00:29:01,670 In this case, the alert one. 256 00:29:04,470 --> 00:29:07,710 The payload was not mine, of course. 257 00:29:07,710 --> 00:29:17,230 I want to thank Gareth Hayes, which compiled a magnificent list on PortSweeger. 258 00:29:17,230 --> 00:29:18,950 So, check it out. 259 00:29:18,950 --> 00:29:29,070 We don't have the original name for the guy that created this payload, but it was the starting point to our attack. 260 00:29:29,550 --> 00:29:31,290 So, what we wanted to do? 261 00:29:31,290 --> 00:29:34,750 Okay, let's be the organizer of the meetup. 262 00:29:34,750 --> 00:29:37,790 Let's steal a meetup group. 263 00:29:37,790 --> 00:29:51,350 We noticed that even using the API, we have some shards were removed, sanitized or whatever, but also they were very easy to bypass. 264 00:29:51,350 --> 00:29:56,250 We just used eval and encoded in Base64. 265 00:29:57,050 --> 00:30:09,850 We wanted to create a payload that will trigger a vulnerable cross-site request forgery endpoint that we found previous. 266 00:30:09,850 --> 00:30:29,670 So, we pointed to the hidden iframe that submitted an auto-submit form that allowed the authenticated organizer to approve another user to co-organizer. 267 00:30:29,670 --> 00:30:33,730 We have a video showing that. 268 00:30:33,730 --> 00:30:40,210 So, we have dropped the payload meetup that is owned by FunkyCat. 269 00:30:40,210 --> 00:30:42,710 As you can see, we have the discussion part. 270 00:30:42,710 --> 00:30:45,550 Pretty easy, it's default on most groups. 271 00:30:45,690 --> 00:30:55,770 So , in members, we have FunkyCat as a leader, organizer, and DavidSopas as a regular member. 272 00:30:56,330 --> 00:30:58,310 This DavidSopas is crazy. 273 00:30:58,310 --> 00:31:00,830 I don't know if it's malicious or not. 274 00:31:00,830 --> 00:31:06,030 So, we triggered our POC, which is the payload. 275 00:31:06,890 --> 00:31:15,190 And after the FunkyCat reloads the page, you will see a new comment. 276 00:31:15,210 --> 00:31:19,870 In this case, it will be an empty comment. 277 00:31:19,870 --> 00:31:21,210 It doesn't say anything. 278 00:31:21,210 --> 00:31:25,610 So, FunkyCat will be like, oh, okay, this guy didn't post anything. 279 00:31:25,610 --> 00:31:26,590 That's weird. 280 00:31:26,590 --> 00:31:32,810 But when you check members, you can see that now DavidSopas is the co-organizer. 281 00:31:32,970 --> 00:31:34,330 How funny is that? 282 00:31:34,330 --> 00:31:37,070 And he can do anything with it. 283 00:31:37,070 --> 00:31:41,830 He has almost the same options than the FunkyCat. 284 00:31:42,010 --> 00:31:43,770 So, cool, right? 285 00:31:43,770 --> 00:31:46,870 But we wanted more, of course. 286 00:31:46,930 --> 00:31:49,830 We are security researchers. 287 00:31:49,830 --> 00:31:51,050 We always want more. 288 00:31:51,050 --> 00:31:53,010 So, give me some money, please. 289 00:31:53,010 --> 00:31:54,510 I love this man, by the way. 290 00:31:54,510 --> 00:31:56,150 Show me the money. 291 00:31:57,010 --> 00:32:00,050 So, we created a new POC. 292 00:32:01,450 --> 00:32:13,210 On the PayPal account, or payments received, the FunkyCat can collect dues to meetup members or charge members for any meetup and anything. 293 00:32:13,210 --> 00:32:20,110 So, you have also a box where FunkyCat can put his PayPal account. 294 00:32:21,110 --> 00:32:25,810 But on your right side, you can see a messy call request. 295 00:32:25,810 --> 00:32:37,150 Just copy-paste from Burp, where we use the API and trigger our payload the same way, inserting it in the discussion part. 296 00:32:37,310 --> 00:32:45,510 And when it triggers, it will post the payload on the discussion part. 297 00:32:45,510 --> 00:32:57,590 And when the FunkyCat goes to his page and refreshes the meetup group, you will get a new message also. 298 00:32:57,590 --> 00:33:01,730 But, again, empty, no problem at all. 299 00:33:02,750 --> 00:33:05,590 But when the random fun meetup... 300 00:33:05,590 --> 00:33:07,950 Yeah, that's random names, okay? 301 00:33:07,950 --> 00:33:12,790 So, it goes to settings, payments received, and guess what? 302 00:33:13,450 --> 00:33:18,910 PayPal account is now sending all your cash to Evil Hacker. 303 00:33:19,310 --> 00:33:21,470 That's cool, right? 304 00:33:21,550 --> 00:33:26,370 Moving to Paulo, because this one is a huge thing. 305 00:33:29,080 --> 00:33:38,860 I'm not sure whether this is gonna be huge, but regarding logging and monitoring, this is what I believe happens most with APIs. 306 00:33:38,860 --> 00:33:48,640 Either they're not producing enough logging, logs have not enough details, or simply API admins are doing nothing with them. 307 00:33:48,640 --> 00:33:56,160 During our account takeover attempts, we never received an email saying that our testing account was under attack. 308 00:33:56,160 --> 00:34:01,260 On the other hand, our security advisories are always received with great surprise. 309 00:34:01,260 --> 00:34:05,080 So we tend to assume that our activities were unnoticed. 310 00:34:05,080 --> 00:34:08,180 And this is not how it is supposed to be. 311 00:34:08,180 --> 00:34:15,580 Logging and monitoring should help organizations to mitigate the risk and act on a timely fashion. 312 00:34:17,680 --> 00:34:20,660 It's time to wrap up this talk. 313 00:34:20,660 --> 00:34:23,740 We're gonna share our final thoughts. 314 00:34:23,740 --> 00:34:28,280 We definitely think that APIs are juicy. 315 00:34:28,280 --> 00:34:36,540 They tend to handle huge amounts of data, and they also leak some of that data. 316 00:34:36,540 --> 00:34:40,180 We still see lots of user authentication issues. 317 00:34:40,180 --> 00:34:45,860 They were common on traditional web applications, and they are still common on APIs. 318 00:34:45,860 --> 00:34:50,460 The same way, we see a lot of authorization issues. 319 00:34:50,460 --> 00:34:58,580 The API scope tends to be big and complex, and authorization is not an easy task. 320 00:34:58,800 --> 00:35:02,560 We have been watching the rising of GraphQL. 321 00:35:02,560 --> 00:35:08,660 We still see REST APIs, as well as XML or JSON-RPC APIs. 322 00:35:08,660 --> 00:35:13,520 But the number of GraphQL is increasing rapidly. 323 00:35:13,520 --> 00:35:20,700 And GraphQL is a very recent technology, and it brings specific security concerns. 324 00:35:20,840 --> 00:35:31,920 Finally, from our experience, organizations are still taking too long to answer and fix vulnerabilities. 325 00:35:31,920 --> 00:35:41,060 And this is something that we will keep working to improve with our research and responsible disclosure. 326 00:35:42,700 --> 00:35:55,020 We don't want to finish before leaving a special thanks to both CheckMarkz and Char49 for the great opportunity to presenting our research in DEF CON. 327 00:35:55,020 --> 00:35:58,700 We are available to answer your questions. 328 00:35:58,700 --> 00:36:02,320 Feel free to reach us on Twitter, and keep safe and strong.