[00:14.120 --> 00:17.000] Hey, thanks again for joining us here in the AppSec Village. [00:17.000 --> 00:21.220] Good morning, good evening, good afternoon, or good night, depending on where you're at in the world. [00:21.220 --> 00:25.180] Kind of a little hard to tell right now since we're not all in one big room together. [00:25.180 --> 00:28.220] But, I've got another exciting talk for you. [00:28.380 --> 00:33.020] The next talk in our agenda is going to be API and Security Top 10. [00:33.080 --> 00:35.600] A guided tour to the wild, wild world. [00:35.600 --> 00:39.860] We've got two speakers this time. We've got David Sopas and Paulo Silva. [00:39.860 --> 00:45.560] David leads a team of security researchers at Checkmarks and is a co-founder of Char49. [00:45.660 --> 00:49.520] With more than 15 years of experience in pin testing and vulnerability research, [00:49.520 --> 00:54.700] he has been acknowledged by companies like Google, Yahoo, eBay, and Microsoft. [00:54.860 --> 00:57.940] After retiring from his bug bounty hunting career, [00:58.400 --> 01:03.480] David now focuses on the Internet of Things security and tries to learn new things each and every day. [01:04.100 --> 01:08.580] Paulo, since his first OWASP local event back in 2010, [01:08.580 --> 01:12.760] has been active in the community, contributing to several OWASP projects. [01:12.760 --> 01:16.060] With over 15 years of professional experience as a software developer, [01:16.060 --> 01:19.620] he is now focused on ethical hacking and security research [01:19.620 --> 01:24.540] with regular collaborations with companies like Char49 and Checkmarks. [01:24.540 --> 01:30.930] He's interested in programming languages, DevSecOps, and web mobile secure coding practices. [01:31.180 --> 01:34.620] Please welcome David and Paulo. [01:36.060 --> 01:40.460] Hello everyone and welcome to the API and Security Top 10, [01:40.460 --> 01:43.480] the guided tour to the wild wild world. [01:43.580 --> 01:50.360] Before we start, I would like to thank and appreciate the opportunity to be at DEF CON, [01:50.360 --> 01:52.920] even if it's in safe mode, [01:52.920 --> 01:58.320] and AppSecVillage for approving our research. [01:58.320 --> 01:59.860] So, thank you. [02:00.160 --> 02:02.000] Let's start. [02:02.000 --> 02:05.700] Well, I will start by presenting who we are, [02:05.700 --> 02:11.960] with a brief description of what APIs are, [02:11.960 --> 02:15.320] the importance in today's software, [02:15.320 --> 02:18.620] the differences from traditional apps. [02:18.620 --> 02:23.340] Then we went through the OWASP API Security Top 10, [02:23.340 --> 02:27.960] talked a little bit about the project and our contribution to that project, [02:27.960 --> 02:32.220] and then guns blazing on the API's wild wild world, [02:32.220 --> 02:36.940] where we show real vulnerabilities on modern web applications [02:36.940 --> 02:40.160] and describe a little bit about our findings. [02:41.740 --> 02:43.300] Who we are. [02:43.300 --> 02:45.280] Well, my name is David Sopas. [02:45.280 --> 02:49.360] I work for Checkmarks since February 16. [02:49.780 --> 02:56.820] I'm currently the security team leader of a very talented group of researchers. [02:56.820 --> 03:03.000] I'm chief operating officer and co-founder of Shard49. [03:03.000 --> 03:08.240] I was a bug bounty hunter a few times ago. [03:08.860 --> 03:17.040] I have around 15 years in penetration testing and security research. [03:17.600 --> 03:22.220] Nowadays, I'm playing more with breaking IoT devices, [03:22.220 --> 03:26.280] specifically using BLE technology, [03:26.280 --> 03:31.740] and focusing on modern web applications, of course, and API. [03:32.540 --> 03:36.460] Some of my work you can already see on TechCrunch, [03:36.460 --> 03:39.880] The Register, Security Week, and ThreatPost. [03:40.100 --> 03:44.300] Sorry about the photo, but I used the pandemic filter. [03:44.840 --> 03:51.200] It was during the quarantine in Portugal, so that's it. [03:51.200 --> 03:53.700] I think it was very appropriate to this event. [03:53.700 --> 03:54.920] Moving on to Paulo. [03:55.620 --> 03:57.440] Hello, and thanks for watching. [03:57.440 --> 04:01.380] My name is Paulo Silva, and it's a great pleasure to be presenting at DEF CON, [04:01.380 --> 04:03.520] especially together with my friend David. [04:03.820 --> 04:06.580] I used to define myself as a freedom enthusiast, [04:06.580 --> 04:10.220] since I love everything related to free and open-source software, [04:10.220 --> 04:14.700] World Wide Web, or cross-countering and bikepacking. [04:14.860 --> 04:17.900] I have more than 15 years as a software developer, [04:17.900 --> 04:21.740] so I know what is plenty of time to have done all sorts of mistakes. [04:22.100 --> 04:25.320] Right now, I do ethical hacking and security research, [04:25.320 --> 04:28.860] and since 2010, I'm a regular OWASP volunteer. [04:30.520 --> 04:35.320] Currently, I'm the OWASP Go Secure Coding Practices project co-leader, [04:35.320 --> 04:39.820] and main collaborator on OWASP API security project. [04:40.000 --> 04:45.040] Meanwhile, I'm used to fill the gap and deliver security awareness sessions in academia. [04:46.800 --> 04:51.040] Before continuing, the mandatory disclaimer. [04:51.040 --> 04:53.940] Hacking systems without permission is crime, [04:53.940 --> 04:59.320] and we are not responsible for misuse of any information we are about to disclose. [05:00.220 --> 05:03.340] Let's talk a bit about APIs. [05:03.700 --> 05:09.420] I like to look for definitions in the dictionary, because words matter. [05:09.420 --> 05:16.040] Nevertheless, I'm not expecting to find a definition for API in the dictionary. [05:16.600 --> 05:23.680] But something interesting about interface, defined as a common boundary of two bodies. [05:23.680 --> 05:26.360] In fact, you can think about APIs this way, [05:26.620 --> 05:31.260] a common language that connected things talk in order to get work done. [05:33.060 --> 05:36.480] APIs have a central role in today's software. [05:36.480 --> 05:41.200] They are the common ground among several types of devices and applications. [05:41.200 --> 05:47.840] A generic language that all them know how to talk, to exchange data and execute functions. [05:48.280 --> 05:52.600] This is different from traditional web applications in many ways. [05:52.600 --> 05:58.400] Before, we had web servers playing this central role, doing the heavy work. [05:58.400 --> 06:04.280] Answering client requests, gathering data from databases and other web services, [06:04.280 --> 06:10.640] gluing everything together, computing the final HTML and returning it back to the client to be rendered. [06:12.040 --> 06:16.080] Nowadays, there are several types of clients behind web browsers. [06:16.080 --> 06:22.240] We have smart bulbs, wearables, cars, surveillance cameras, etc, etc, etc. [06:22.400 --> 06:32.100] All these clients use APIs to make their capabilities available to other clients and to communicate with each other. [06:32.100 --> 06:35.480] Clients are now more powerful than they were before. [06:35.480 --> 06:41.100] In modern web applications, there is a clear separation between front-end and back-end. [06:41.100 --> 06:48.100] The front-end nowadays is a bunch of JavaScript and CSS providing rich user interfaces to collect data, [06:48.640 --> 06:57.080] send the data to several APIs, making it generally available to all clients regardless their type. [06:57.080 --> 07:07.900] I think this is pretty much about APIs and we should move on to the OWASP API top 10 with David. [07:07.900 --> 07:11.420] So, OWASP API security top 10. [07:12.360 --> 07:23.280] You may have already heard about OWASP. In its own words, it is a non-profit foundation that works to improve the security of software. [07:23.280 --> 07:28.960] OWASP top 10 is one of the flagship projects and most of you should already know it already. [07:28.960 --> 07:38.040] It has played an enormous role to bring security awareness into organizations, both to management and dev teams. [07:38.040 --> 07:43.260] But we have seen very specific API related issues popping up. [07:43.260 --> 07:55.080] We should learn from past mistakes and R. Zialon and Inon Skedi decided to start the OWASP API security project to address API specific issues. [07:55.080 --> 08:04.400] The document follows the same approach and popular OWASP top 10 for readability purposes, but it's 100% API oriented. [08:05.980 --> 08:07.840] Our contribute. [08:08.120 --> 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. [08:18.520 --> 08:20.320] So we had to research. [08:20.320 --> 08:34.040] 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, [08:34.040 --> 08:39.060] but we had to review it and pick only the API related issues. [08:39.060 --> 08:46.740] So while reviewing the reports and the write-ups, we start standardizing the categorization and grouping things together. [08:46.740 --> 08:52.680] After a few months, we were able to compute a statistical top 10. [08:52.680 --> 09:00.620] Security risk, of course, was using the OWASP risk rating methodology. [09:00.660 --> 09:11.560] We drafted the first OWASP API security top 10 and asked several entities, organizations and individuals with relevant AppSec experience in the API field, [09:11.560 --> 09:14.020] at least to get us some feedback. [09:14.020 --> 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. [09:25.280 --> 09:32.960] By the end of 2019, the final version was published and we were very happy with it. [09:32.960 --> 09:40.480] Then we went wild to validate how accurate the OWASP API security top 10 2019 was. [09:40.480 --> 09:46.620] I hope you can have the opportunity to download it and see it. [09:47.880 --> 09:50.560] APIs in the wild, wild world. [09:51.220 --> 09:52.360] Our research. [09:53.960 --> 10:03.440] Our focus was only on high-profile web applications and, of course, focusing on the API. [10:03.440 --> 10:12.680] We want to map all the vulnerabilities that we found on the OWASP top 10 2019. [10:13.260 --> 10:22.540] So, you may ask what was our biggest problem, if I can say that. [10:23.220 --> 10:33.380] And, yeah, it was the responsible disclosure because many companies didn't reply or just didn't care about security. [10:33.380 --> 10:39.680] That was the most challenging issue that we encountered. [10:40.340 --> 10:44.900] On our research, we tested 8 APIs. [10:44.900 --> 10:54.980] We discovered 28 API issues that we categorized as you can see on the right table. [10:54.980 --> 11:01.880] We got a minimum CVSS 2.7 and a 7.7 max. [11:02.880 --> 11:07.380] We found 7 broken user authentication. [11:07.520 --> 11:20.220] With 5 issues, we have broken object level authorization or BOLA and also with 5 excessive data exposure. [11:20.480 --> 11:23.660] Security misconfiguration was 4. [11:23.660 --> 11:26.780] Broken function level authorization, 3. [11:26.780 --> 11:31.240] And also with 3, lack of resources and rate limiting, 3. [11:31.240 --> 11:36.380] Finishing with 1 result on injection, not so common anymore. [11:38.180 --> 11:41.440] Findings. Moving on to Paolo. [11:45.440 --> 11:49.620] Okay, let's start with the broken object level authorization. [11:49.620 --> 11:54.360] You may know this by IDOR or Insecure Direct Object Reference. [11:54.360 --> 12:01.880] But while writing OWASP API security top 10, we decided to rename it since IDOR is not a very accurate name. [12:02.640 --> 12:09.940] In this case, we found 2 exposed APIs, a GraphQL and a REST one. [12:09.940 --> 12:13.780] Both vulnerable to broken object level authorization. [12:14.660 --> 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. [12:22.080 --> 12:24.180] Nothing more, nothing less. [12:24.280 --> 12:30.160] This is valid for resources like profile but also to their fields. [12:30.160 --> 12:34.560] Of course, we can try to guess everything or use word lists. [12:34.560 --> 12:44.480] But it becomes even more interesting if you find another vulnerability like a security misconfiguration allowing you to query that information. [12:44.560 --> 12:52.200] More details about the security misconfiguration specific to GraphQL and its specific section. [12:52.200 --> 12:56.840] You just have to wait a few more issues and we will get there. [12:57.500 --> 13:01.400] By now, let's focus on the requests on the left side. [13:01.400 --> 13:06.120] We are looking for a specific profile based on its slug. [13:06.120 --> 13:12.110] The slug is public information since it's part of the user's public URL. [13:12.380 --> 13:15.920] On the right side, we have the API response. [13:15.920 --> 13:27.200] We can see user's public URL, the slug and also something that points the profile to be private. [13:27.200 --> 13:30.420] But nowadays, we never know what private means. [13:30.520 --> 13:40.000] We have several other properties but there's another one, the ID, which we will use with the REST API. [13:41.000 --> 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. [13:53.400 --> 14:02.040] We got additional information including billing information with full address and tax ID number. [14:02.640 --> 14:09.020] At least this time, API doesn't say that the user resource is private. [14:09.020 --> 14:15.640] But note that both requests were anonymous. There was no authentication nor authorization. [14:16.040 --> 14:21.460] I think this was a good warm-up. We can continue with David. [14:23.740 --> 14:28.520] Broken user authentication. In this case, SoundCloud. [14:28.520 --> 14:33.920] Our final objective was to get account takeover and we did it. [14:33.920 --> 14:43.600] On SoundCloud, which is already disclosed this issue, I can give you a brief description of what we did. [14:43.600 --> 14:52.760] On user account lockout, based on failed login attempt, is something that we don't see often. [14:52.760 --> 15:00.540] In this case, the API was rate-limited. [15:00.540 --> 15:05.040] So, nevertheless, it was possible to bypass and we will show you how. [15:05.540 --> 15:11.120] So, chaining the rate-limited bypass with the user enumeration issue that we found, [15:11.120 --> 15:15.860] we were able to accomplish the account takeover via credential stuffing attack. [15:17.700 --> 15:25.200] This is a typical user enumeration scenario where we abuse the recover password mechanism. [15:25.200 --> 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. [15:36.100 --> 15:41.940] Rate-limiting bypass was something fun, because at least it was the first time we saw it. [15:41.940 --> 15:47.760] It was based on the user agent, the device ID and the signature. [15:47.760 --> 15:52.220] So, both device ID and signature was computed client-side. [15:52.520 --> 16:02.240] Instead of reversing the JavaScript logic, we gathered three different combinations to be randomly picked by our brute-force script. [16:02.240 --> 16:11.540] After a first fixed attempt, we will also use different EIPs by using Tor, forcing different as-it-nodes. [16:12.000 --> 16:18.780] Rate-limiting is very important, of course, and it should be very restrictive for authentication endpoints, [16:18.780 --> 16:24.020] but it can also not be enough to prevent what the user account lockout does, [16:24.020 --> 16:28.480] which should be implemented both authentication and rate-limited. [16:29.420 --> 16:36.620] So, this is the example that we did with a single-threaded POC running in an ordinary laptop. [16:36.620 --> 16:45.180] For sure, if we use concurrency or parallelism and cloud-based approach, we have done it much faster, for sure. [16:46.980 --> 16:56.600] So, in the end, this is the access token we can have and the account takeover is completed to follow. [17:03.290 --> 17:06.750] Let's talk about excessive data exposure. [17:06.770 --> 17:10.670] This is probably one of my favorite findings. [17:11.570 --> 17:15.930] We started with the user enumeration issue on the recovery password mechanism [17:15.930 --> 17:22.190] and later a security misconfiguration allowing us to leverage the attack. [17:22.590 --> 17:27.490] The recovery password required the user to provide its email address on the front-end, [17:27.490 --> 17:37.130] which then issues an API request to retrieve a list of available delivery channels, either email or phone. [17:37.130 --> 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. [17:45.850 --> 17:55.270] In this workflow, we noticed that a URL, including a JSON web token, were provided for each delivery method. [17:55.270 --> 18:00.410] So, we took the phone URL and decoded the JSON web token. [18:00.830 --> 18:10.450] Then we found that the actual user phone number is included in the JSON web token payload section, [18:10.450 --> 18:14.470] meaning that we can exchange user emails by phone numbers. [18:14.810 --> 18:21.810] Note that these API requests are anonymous, since they are aimed to recover passwords. [18:21.810 --> 18:31.110] We decided to go further and do this for an arbitrary list of email addresses that we gathered from pastebin.com. [18:31.110 --> 18:39.970] It had 169 email addresses and we got 7 user accounts with email and phone number. [18:40.690 --> 18:44.570] Meanwhile, we found a security misconfiguration. [18:44.570 --> 18:51.130] In fact, we found an exposed error log file, including some sensitive information, [18:51.130 --> 18:57.550] but the most interesting one was the location of some internal files. [18:57.750 --> 19:04.230] Luckily, these files were also exposed and publicly accessible. [19:04.230 --> 19:07.330] And this is how some of them look like. [19:07.330 --> 19:18.190] They were mailing reports with valid user account emails and also the mailing subject. [19:18.190 --> 19:25.790] So, just by themselves, they were good enough to be used for a phishing campaign. [19:25.790 --> 19:34.410] But we could even enrich it with phone numbers, complete the info and drive some phishing or smishing attack. [19:38.280 --> 19:42.360] APIs tend to handle huge amounts of data. [19:42.360 --> 19:46.000] And some of them also leak part of that data. [19:46.000 --> 19:48.480] You may know Meetup. [19:48.480 --> 19:57.500] Meetup offers pro accounts, which give you access to unlimited groups and targeted communications to members. [19:57.500 --> 20:03.940] You get several other features, all of them for $30 per month per group. [20:04.440 --> 20:08.280] And, in fact, you also get access to free email addresses. [20:09.040 --> 20:17.500] Regardless of what privacy settings you choose and what Meetup says, that they won't give your email address to anyone, [20:17.500 --> 20:27.260] 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. [20:27.860 --> 20:38.960] And we did this for 38,504 user profiles just on the WordPress network. [20:39.380 --> 20:42.760] I think it's quite huge. [20:42.760 --> 20:47.560] Let's continue with David with lack of resources and rate limiting. [20:48.740 --> 20:56.700] Well, with lack of resources and rate limiting, the final objective was user enumeration. [20:56.700 --> 21:01.820] So, what we have is improper rate limiting. [21:02.300 --> 21:07.520] And, in the end, we got the user enumeration. [21:07.520 --> 21:10.540] In this screenshot you can see it. [21:10.540 --> 21:18.440] Because, to be fair, the Meetup, which is the target, had the rate limiting defined on... [21:18.440 --> 21:20.700] It followed the best practice. [21:20.700 --> 21:26.460] You can see the X rate limit custom response header. [21:26.460 --> 21:33.660] But, when we tried to enumerate members, we noticed that something was strange. [21:34.440 --> 21:41.620] We noticed that after a few rate-limited requests, it just got stuck. [21:41.620 --> 21:48.300] So, I don't know if it was a bug on the server side or something like that. [21:48.300 --> 21:56.780] Because it allowed us to continue and did not lock our attempt to enumerate. [21:57.060 --> 22:00.840] Just a small preview, nothing fancy. [22:00.840 --> 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. [22:19.860 --> 22:27.240] Ok, so, just simple enumeration, including the username, user location, the profile photo... [22:27.860 --> 22:33.140] And, by the way, you can see on the bio that it's the co-founder and former CTO. [22:34.560 --> 22:38.860] Of Meetup and PM on Facebook. [22:38.860 --> 22:41.400] So, it was... well, it was the number 2. [22:41.400 --> 22:50.680] So, I'm supposing the idea was very close to be the founder or something very important on the Meetup. [22:50.680 --> 22:54.140] But, just to show you that a simple... [22:54.920 --> 23:01.140] If you don't control and test the rate-limited protection... [23:03.140 --> 23:06.640] You need to make serious. You better test it. [23:06.640 --> 23:12.220] It's not just put a header and didn't test it and forget it. [23:12.220 --> 23:14.660] You need to control it, ok? [23:14.660 --> 23:16.180] So, to follow. [23:24.480 --> 23:30.320] Let's talk about the second authorization issue in the OWASP API security top 10. [23:30.380 --> 23:32.660] Broken function level authorization. [23:32.840 --> 23:35.600] We began with broken object level authorization. [23:35.600 --> 23:38.000] And you should expect something similar. [23:38.000 --> 23:45.100] But instead of requesting objects by their unique identifier, we're gonna ask APIs to execute functions. [23:45.100 --> 23:48.240] Either regular user or admin ones. [23:48.720 --> 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. [23:55.520 --> 24:02.100] This pandemic, among other severe consequences, also created a new battleground. [24:02.100 --> 24:04.860] Conferencing tools and services. [24:04.860 --> 24:11.640] By the way, this finding was yet another great job by our friends João Moraes and Guilhom Lopes. [24:11.980 --> 24:18.180] João Moraes is also presenting at DEF CON this year together with Pedro Umblino, another friend of us. [24:18.180 --> 24:22.220] And you should not lose the chance to watch their talk. [24:23.660 --> 24:30.300] In addition to the audio and video features, this conferencing tool also offers a user chat. [24:30.300 --> 24:37.920] I think they know that users need a way to ask others whether they can hear them. [24:38.180 --> 24:43.160] I'm not sure whether this is foolproof, but let's see what we found. [24:45.020 --> 24:49.940] While joining the meeting, we noticed an API request like the one on the left. [24:49.940 --> 24:53.520] The response on the right returns a list of participants. [24:54.380 --> 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. [25:04.380 --> 25:19.440] So, simply iterating over viewer code ID, we got exactly 1496 email addresses from other meeting participants. [25:19.440 --> 25:26.720] And we also got 673 phone numbers from the same participants. [25:28.320 --> 25:31.660] Let's discuss security misconfigurations with David. [25:34.530 --> 25:36.570] Security misconfiguration... [25:38.210 --> 25:46.730] Well, with security misconfiguration we did found a couple of things, but please don't expect too much from here. [25:46.730 --> 25:59.990] It's really a bunch of nothing. We did found stack traces and one of them, not related to the stack trace, one of the security misconfiguration was a GraphQL introspection. [26:00.370 --> 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. [26:10.950 --> 26:21.200] Okay, so stack trace on an handled Java exception. So, this type of vulnerability is like boring, moving along. [26:21.590 --> 26:27.220] Another stack trace, but this time with more style. It's Node.js, an handled exception. [26:27.870 --> 26:31.710] Well, at least it's clean up your own mess, right? [26:33.330 --> 26:36.950] Okay, finally, something more clean. [26:36.950 --> 26:41.990] You know that development tools should not be deployed in production, right? [26:43.790 --> 26:49.270] And yes, this is the GraphQL introspection attack. [26:50.170 --> 26:57.190] And please, GraphQL introspection should be disabled in production, like I said before. [26:57.190 --> 27:05.910] This will give the attacker the opportunity to get the structure of your database and many more information. [27:05.910 --> 27:10.090] So, devs, keep that in mind. [27:10.150 --> 27:16.950] Also, unique ID is Base64 obfuscated. [27:16.950 --> 27:22.530] This is what we underlined on the Burp screenshot. [27:22.530 --> 27:27.170] By the way, Base64 is encoding and not obfuscated. [27:27.190 --> 27:31.230] But anyway, thanks for the detailed explanation. [27:32.050 --> 27:38.290] Injection, one of my favorite sections of this presentation. [27:38.610 --> 27:40.070] And guess what? [27:40.950 --> 27:47.610] We changed the vulnerabilities with cross-site scripting and cross-site request forgery. [27:47.610 --> 27:57.070] And in the end, well, we have the cool scenarios to present. [27:57.470 --> 27:59.710] Guess what? Meetup. [27:59.790 --> 28:02.070] All your meetup belong to us. [28:02.730 --> 28:05.050] What was the real objective? [28:05.050 --> 28:07.670] Well, I used meetup. [28:07.670 --> 28:16.570] And when I see a discussion part where you could post some comments and messages to the group itself, [28:16.570 --> 28:21.710] it immediately wanted me to pop up some alert box. [28:21.710 --> 28:28.490] And coming from a guy that loves and keeps studying cross-site scripting attacks, [28:28.490 --> 28:32.050] it was something that I would like to do. [28:33.370 --> 28:39.750] The frontend immediately won't allow it and sanitized most of the content that I posted. [28:39.750 --> 28:44.950] So, after a while and checking the burp proxy logs, [28:44.950 --> 28:49.810] I noticed that some requests were being made to the API. [28:49.810 --> 28:52.010] So, API did the job. [28:52.930 --> 28:58.790] I did found a payload that immediately triggered what I wanted. [28:58.790 --> 29:01.670] In this case, the alert one. [29:04.470 --> 29:07.710] The payload was not mine, of course. [29:07.710 --> 29:17.230] I want to thank Gareth Hayes, which compiled a magnificent list on PortSweeger. [29:17.230 --> 29:18.950] So, check it out. [29:18.950 --> 29:23.170] We don't have the original name for the guy that created this payload, [29:23.170 --> 29:29.070] but it was the starting point to our attack. [29:29.550 --> 29:31.290] So, what we wanted to do? [29:31.290 --> 29:34.750] Okay, let's be the organizer of the meetup. [29:34.750 --> 29:37.790] Let's steal a meetup group. [29:37.790 --> 29:45.310] We noticed that even using the API, we have some shards were removed, sanitized or whatever, [29:45.310 --> 29:51.350] but also they were very easy to bypass. [29:51.350 --> 29:56.250] We just used eval and encoded in Base64. [29:57.050 --> 30:09.850] We wanted to create a payload that will trigger a vulnerable cross-site request forgery endpoint that we found previous. [30:09.850 --> 30:19.250] So, we pointed to the hidden iframe that submitted an auto-submit form [30:19.850 --> 30:29.670] that allowed the authenticated organizer to approve another user to co-organizer. [30:29.670 --> 30:33.730] We have a video showing that. [30:33.730 --> 30:40.210] So, we have dropped the payload meetup that is owned by FunkyCat. [30:40.210 --> 30:42.710] As you can see, we have the discussion part. [30:42.710 --> 30:45.550] Pretty easy, it's default on most groups. [30:45.690 --> 30:55.770] So, in members, we have FunkyCat as a leader, organizer, and DavidSopas as a regular member. [30:56.330 --> 30:58.310] This DavidSopas is crazy. [30:58.310 --> 31:00.830] I don't know if it's malicious or not. [31:00.830 --> 31:06.030] So, we triggered our POC, which is the payload. [31:06.890 --> 31:15.190] And after the FunkyCat reloads the page, you will see a new comment. [31:15.210 --> 31:19.870] In this case, it will be an empty comment. [31:19.870 --> 31:21.210] It doesn't say anything. [31:21.210 --> 31:25.610] So, FunkyCat will be like, oh, okay, this guy didn't post anything. [31:25.610 --> 31:26.590] That's weird. [31:26.590 --> 31:32.810] But when you check members, you can see that now DavidSopas is the co-organizer. [31:32.970 --> 31:34.330] How funny is that? [31:34.330 --> 31:37.070] And he can do anything with it. [31:37.070 --> 31:41.830] He has almost the same options than the FunkyCat. [31:42.010 --> 31:43.770] So, cool, right? [31:43.770 --> 31:46.870] But we wanted more, of course. [31:46.930 --> 31:49.830] We are security researchers. [31:49.830 --> 31:51.050] We always want more. [31:51.050 --> 31:53.010] So, give me some money, please. [31:53.010 --> 31:54.510] I love this man, by the way. [31:54.510 --> 31:56.150] Show me the money. [31:57.010 --> 32:00.050] So, we created a new POC. [32:01.450 --> 32:09.570] On the PayPal account, or payments received, the FunkyCat can collect dues to meetup members [32:09.570 --> 32:13.210] or charge members for any meetup and anything. [32:13.210 --> 32:20.110] So, you have also a box where FunkyCat can put his PayPal account. [32:21.110 --> 32:25.810] But on your right side, you can see a messy call request. [32:25.810 --> 32:33.530] Just copy-paste from Burp, where we use the API and trigger our payload the same way, [32:33.530 --> 32:37.150] inserting it in the discussion part. [32:37.310 --> 32:45.510] And when it triggers, it will post the payload on the discussion part. [32:45.510 --> 32:54.470] And when the FunkyCat goes to his page and refreshes the meetup group, [32:54.470 --> 32:57.590] you will get a new message also. [32:57.590 --> 33:01.730] But, again, empty, no problem at all. [33:02.750 --> 33:05.590] But when the random fun meetup... [33:05.590 --> 33:07.950] Yeah, that's random names, okay? [33:07.950 --> 33:12.790] So, it goes to settings, payments received, and guess what? [33:13.450 --> 33:18.910] PayPal account is now sending all your cash to Evil Hacker. [33:19.310 --> 33:21.470] That's cool, right? [33:21.550 --> 33:26.370] Moving to Paulo, because this one is a huge thing. [33:29.080 --> 33:33.980] I'm not sure whether this is gonna be huge, but regarding logging and monitoring, [33:33.980 --> 33:38.860] this is what I believe happens most with APIs. [33:38.860 --> 33:45.160] Either they're not producing enough logging, logs have not enough details, [33:45.160 --> 33:48.640] or simply API admins are doing nothing with them. [33:48.640 --> 33:56.160] During our account takeover attempts, we never received an email saying that our testing account was under attack. [33:56.160 --> 34:01.260] On the other hand, our security advisories are always received with great surprise. [34:01.260 --> 34:05.080] So we tend to assume that our activities were unnoticed. [34:05.080 --> 34:08.180] And this is not how it is supposed to be. [34:08.180 --> 34:15.580] Logging and monitoring should help organizations to mitigate the risk and act on a timely fashion. [34:17.680 --> 34:20.660] It's time to wrap up this talk. [34:20.660 --> 34:23.740] We're gonna share our final thoughts. [34:23.740 --> 34:28.280] We definitely think that APIs are juicy. [34:28.280 --> 34:36.540] They tend to handle huge amounts of data, and they also leak some of that data. [34:36.540 --> 34:40.180] We still see lots of user authentication issues. [34:40.180 --> 34:45.860] They were common on traditional web applications, and they are still common on APIs. [34:45.860 --> 34:50.460] The same way, we see a lot of authorization issues. [34:50.460 --> 34:58.580] The API scope tends to be big and complex, and authorization is not an easy task. [34:58.800 --> 35:02.560] We have been watching the rising of GraphQL. [35:02.560 --> 35:08.660] We still see REST APIs, as well as XML or JSON-RPC APIs. [35:08.660 --> 35:13.520] But the number of GraphQL is increasing rapidly. [35:13.520 --> 35:20.700] And GraphQL is a very recent technology, and it brings specific security concerns. [35:20.840 --> 35:31.920] Finally, from our experience, organizations are still taking too long to answer and fix vulnerabilities. [35:31.920 --> 35:41.060] And this is something that we will keep working to improve with our research and responsible disclosure. [35:42.700 --> 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. [35:55.020 --> 35:58.700] We are available to answer your questions. [35:58.700 --> 36:02.320] Feel free to reach us on Twitter, and keep safe and strong.