Hey, thanks again for joining us here in the AppSec Village. Good morning, good evening, good afternoon, or good night, depending on where you're at in the world. Kind of a little hard to tell right now since we're not all in one big room together. But, I've got another exciting talk for you. The next talk in our agenda is going to be API and Security Top 10. A guided tour to the wild, wild world. We've got two speakers this time. We've got David Sopas and Paulo Silva. David leads a team of security researchers at Checkmarks and is a co-founder of Char49. 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. 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. Paulo, since his first OWASP local event back in 2010, has been active in the community, contributing to several OWASP projects. 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. He's interested in programming languages, DevSecOps, and web mobile secure coding practices. Please welcome David and Paulo. Hello everyone and welcome to the API and Security Top 10, the guided tour to the wild wild world. 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. So, thank you. Let's start. 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. 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. Who we are. Well, my name is David Sopas. I work for Checkmarks since February 16. I'm currently the security team leader of a very talented group of researchers. I'm chief operating officer and co-founder of Shard49. I was a bug bounty hunter a few times ago. I have around 15 years in penetration testing and security research. Nowadays, I'm playing more with breaking IoT devices, specifically using BLE technology, and focusing on modern web applications, of course, and API. Some of my work you can already see on TechCrunch, The Register, Security Week, and ThreatPost. Sorry about the photo, but I used the pandemic filter. It was during the quarantine in Portugal, so that's it. I think it was very appropriate to this event. Moving on to Paulo. Hello, and thanks for watching. My name is Paulo Silva, and it's a great pleasure to be presenting at DEF CON, especially together with my friend David. 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. 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. Right now, I do ethical hacking and security research, and since 2010, I'm a regular OWASP volunteer. Currently, I'm the OWASP Go Secure Coding Practices project co-leader, and main collaborator on OWASP API security project. Meanwhile, I'm used to fill the gap and deliver security awareness sessions in academia. Before continuing, the mandatory disclaimer. Hacking systems without permission is crime, and we are not responsible for misuse of any information we are about to disclose. Let's talk a bit about APIs. I like to look for definitions in the dictionary, because words matter. Nevertheless, I'm not expecting to find a definition for API in the dictionary. But something interesting about interface, defined as a common boundary of two bodies. In fact, you can think about APIs this way, a common language that connected things talk in order to get work done. APIs have a central role in today's software. They are the common ground among several types of devices and applications. A generic language that all them know how to talk, to exchange data and execute functions. This is different from traditional web applications in many ways. Before, we had web servers playing this central role, doing the heavy work. 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. Nowadays, there are several types of clients behind web browsers. We have smart bulbs, wearables, cars, surveillance cameras, etc, etc, etc. All these clients use APIs to make their capabilities available to other clients and to communicate with each other. Clients are now more powerful than they were before. In modern web applications, there is a clear separation between front-end and back-end. 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. I think this is pretty much about APIs and we should move on to the OWASP API top 10 with David. So, OWASP API security top 10. 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. OWASP top 10 is one of the flagship projects and most of you should already know it already. It has played an enormous role to bring security awareness into organizations, both to management and dev teams. But we have seen very specific API related issues popping up. 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. The document follows the same approach and popular OWASP top 10 for readability purposes, but it's 100% API oriented. Our contribute. Vendors have been doing business as usual and there is no API specific data for a public call for data like other OWASP projects. So we had to research. 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. So while reviewing the reports and the write-ups, we start standardizing the categorization and grouping things together. After a few months, we were able to compute a statistical top 10. Security risk, of course, was using the OWASP risk rating methodology. 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. 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. By the end of 2019, the final version was published and we were very happy with it. Then we went wild to validate how accurate the OWASP API security top 10 2019 was. I hope you can have the opportunity to download it and see it. APIs in the wild, wild world. Our research. Our focus was only on high-profile web applications and, of course, focusing on the API. We want to map all the vulnerabilities that we found on the OWASP top 10 2019. So, you may ask what was our biggest problem, if I can say that. And, yeah, it was the responsible disclosure because many companies didn't reply or just didn't care about security. That was the most challenging issue that we encountered. On our research, we tested 8 APIs. We discovered 28 API issues that we categorized as you can see on the right table. We got a minimum CVSS 2.7 and a 7.7 max. We found 7 broken user authentication. With 5 issues, we have broken object level authorization or BOLA and also with 5 excessive data exposure. Security misconfiguration was 4. Broken function level authorization, 3. And also with 3, lack of resources and rate limiting, 3. Finishing with 1 result on injection, not so common anymore. Findings. Moving on to Paolo. Okay, let's start with the broken object level authorization. You may know this by IDOR or Insecure Direct Object Reference. But while writing OWASP API security top 10, we decided to rename it since IDOR is not a very accurate name. In this case, we found 2 exposed APIs, a GraphQL and a REST one. Both vulnerable to broken object level authorization. As you may know, GraphQL is not like REST and you should ask for what you need and you will get exactly that. Nothing more, nothing less. This is valid for resources like profile but also to their fields. Of course, we can try to guess everything or use word lists. But it becomes even more interesting if you find another vulnerability like a security misconfiguration allowing you to query that information. More details about the security misconfiguration specific to GraphQL and its specific section. You just have to wait a few more issues and we will get there. By now, let's focus on the requests on the left side. We are looking for a specific profile based on its slug. The slug is public information since it's part of the user's public URL. On the right side, we have the API response. We can see user's public URL, the slug and also something that points the profile to be private. But nowadays, we never know what private means. We have several other properties but there's another one, the ID, which we will use with the REST API. We took the ID property we got from the GraphQL API and we used it to request a user on the REST API. We got additional information including billing information with full address and tax ID number. At least this time, API doesn't say that the user resource is private. But note that both requests were anonymous. There was no authentication nor authorization. I think this was a good warm-up. We can continue with David. Broken user authentication. In this case, SoundCloud. Our final objective was to get account takeover and we did it. On SoundCloud, which is already disclosed this issue, I can give you a brief description of what we did. On user account lockout, based on failed login attempt, is something that we don't see often. In this case, the API was rate-limited. So, nevertheless, it was possible to bypass and we will show you how. 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. This is a typical user enumeration scenario where we abuse the recover password mechanism. 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. Rate-limiting bypass was something fun, because at least it was the first time we saw it. It was based on the user agent, the device ID and the signature. So, both device ID and signature was computed client-side. Instead of reversing the JavaScript logic, we gathered three different combinations to be randomly picked by our brute-force script. After a first fixed attempt, we will also use different EIPs by using Tor, forcing different as-it-nodes. 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. So, this is the example that we did with a single-threaded POC running in an ordinary laptop. For sure, if we use concurrency or parallelism and cloud-based approach, we have done it much faster, for sure. So, in the end, this is the access token we can have and the account takeover is completed to follow. Let's talk about excessive data exposure. This is probably one of my favorite findings. We started with the user enumeration issue on the recovery password mechanism and later a security misconfiguration allowing us to leverage the attack. 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. The user can pick one on the front-end and then a one-time password is delivered so that it can recover his password. In this workflow, we noticed that a URL, including a JSON web token, were provided for each delivery method. So, we took the phone URL and decoded the JSON web token. 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. Note that these API requests are anonymous, since they are aimed to recover passwords. We decided to go further and do this for an arbitrary list of email addresses that we gathered from pastebin.com. It had 169 email addresses and we got 7 user accounts with email and phone number. Meanwhile, we found a security misconfiguration. 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. Luckily, these files were also exposed and publicly accessible. And this is how some of them look like. They were mailing reports with valid user account emails and also the mailing subject. So, just by themselves, they were good enough to be used for a phishing campaign. But we could even enrich it with phone numbers, complete the info and drive some phishing or smishing attack. APIs tend to handle huge amounts of data. And some of them also leak part of that data. You may know Meetup. Meetup offers pro accounts, which give you access to unlimited groups and targeted communications to members. You get several other features, all of them for $30 per month per group. And, in fact, you also get access to free email addresses. 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. And we did this for 38,504 user profiles just on the WordPress network. I think it's quite huge. Let's continue with David with lack of resources and rate limiting. Well, with lack of resources and rate limiting, the final objective was user enumeration. So, what we have is improper rate limiting. And, in the end, we got the user enumeration. In this screenshot you can see it. Because, to be fair, the Meetup, which is the target, had the rate limiting defined on... It followed the best practice. You can see the X rate limit custom response header. But, when we tried to enumerate members, we noticed that something was strange. We noticed that after a few rate-limited requests, it just got stuck. So, I don't know if it was a bug on the server side or something like that. Because it allowed us to continue and did not lock our attempt to enumerate. Just a small preview, nothing fancy. But, you can see that, in the end, after a few requests, we did find a lot of user names that we could use. Ok, so, just simple enumeration, including the username, user location, the profile photo... And, by the way, you can see on the bio that it's the co-founder and former CTO. Of Meetup and PM on Facebook. So, it was... well, it was the number 2. So, I'm supposing the idea was very close to be the founder or something very important on the Meetup. But, just to show you that a simple... If you don't control and test the rate-limited protection... You need to make serious. You better test it. It's not just put a header and didn't test it and forget it. You need to control it, ok? So, to follow. Let's talk about the second authorization issue in the OWASP API security top 10. Broken function level authorization. We began with broken object level authorization. And you should expect something similar. But instead of requesting objects by their unique identifier, we're gonna ask APIs to execute functions. Either regular user or admin ones. We're glad you stick with us until here because we didn't have the chance to talk about COVID-19 pandemic yet. This pandemic, among other severe consequences, also created a new battleground. Conferencing tools and services. By the way, this finding was yet another great job by our friends João Moraes and Guilhom Lopes. João Moraes is also presenting at DEF CON this year together with Pedro Umblino, another friend of us. And you should not lose the chance to watch their talk. In addition to the audio and video features, this conferencing tool also offers a user chat. I think they know that users need a way to ask others whether they can hear them. I'm not sure whether this is foolproof, but let's see what we found. While joining the meeting, we noticed an API request like the one on the left. The response on the right returns a list of participants. 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. So, simply iterating over viewer code ID, we got exactly 1496 email addresses from other meeting participants. And we also got 673 phone numbers from the same participants. Let's discuss security misconfigurations with David. Security misconfiguration... Well, with security misconfiguration we did found a couple of things, but please don't expect too much from here. 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. 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. Okay, so stack trace on an handled Java exception. So, this type of vulnerability is like boring, moving along. Another stack trace, but this time with more style. It's Node.js, an handled exception. Well, at least it's clean up your own mess, right? Okay, finally, something more clean. You know that development tools should not be deployed in production, right? And yes, this is the GraphQL introspection attack. And please, GraphQL introspection should be disabled in production, like I said before. This will give the attacker the opportunity to get the structure of your database and many more information. So, devs, keep that in mind. Also, unique ID is Base64 obfuscated. This is what we underlined on the Burp screenshot. By the way, Base64 is encoding and not obfuscated. But anyway, thanks for the detailed explanation. Injection, one of my favorite sections of this presentation. And guess what? We changed the vulnerabilities with cross-site scripting and cross-site request forgery. And in the end, well, we have the cool scenarios to present. Guess what? Meetup. All your meetup belong to us. What was the real objective? Well, I used meetup. 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. And coming from a guy that loves and keeps studying cross-site scripting attacks, it was something that I would like to do. The frontend immediately won't allow it and sanitized most of the content that I posted. So, after a while and checking the burp proxy logs, I noticed that some requests were being made to the API. So, API did the job. I did found a payload that immediately triggered what I wanted. In this case, the alert one. The payload was not mine, of course. I want to thank Gareth Hayes, which compiled a magnificent list on PortSweeger. So, check it out. We don't have the original name for the guy that created this payload, but it was the starting point to our attack. So, what we wanted to do? Okay, let's be the organizer of the meetup. Let's steal a meetup group. We noticed that even using the API, we have some shards were removed, sanitized or whatever, but also they were very easy to bypass. We just used eval and encoded in Base64. We wanted to create a payload that will trigger a vulnerable cross-site request forgery endpoint that we found previous. 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. We have a video showing that. So, we have dropped the payload meetup that is owned by FunkyCat. As you can see, we have the discussion part. Pretty easy, it's default on most groups. So, in members, we have FunkyCat as a leader, organizer, and DavidSopas as a regular member. This DavidSopas is crazy. I don't know if it's malicious or not. So, we triggered our POC, which is the payload. And after the FunkyCat reloads the page, you will see a new comment. In this case, it will be an empty comment. It doesn't say anything. So, FunkyCat will be like, oh, okay, this guy didn't post anything. That's weird. But when you check members, you can see that now DavidSopas is the co-organizer. How funny is that? And he can do anything with it. He has almost the same options than the FunkyCat. So, cool, right? But we wanted more, of course. We are security researchers. We always want more. So, give me some money, please. I love this man, by the way. Show me the money. So, we created a new POC. On the PayPal account, or payments received, the FunkyCat can collect dues to meetup members or charge members for any meetup and anything. So, you have also a box where FunkyCat can put his PayPal account. But on your right side, you can see a messy call request. Just copy-paste from Burp, where we use the API and trigger our payload the same way, inserting it in the discussion part. And when it triggers, it will post the payload on the discussion part. And when the FunkyCat goes to his page and refreshes the meetup group, you will get a new message also. But, again, empty, no problem at all. But when the random fun meetup... Yeah, that's random names, okay? So, it goes to settings, payments received, and guess what? PayPal account is now sending all your cash to Evil Hacker. That's cool, right? Moving to Paulo, because this one is a huge thing. I'm not sure whether this is gonna be huge, but regarding logging and monitoring, this is what I believe happens most with APIs. Either they're not producing enough logging, logs have not enough details, or simply API admins are doing nothing with them. During our account takeover attempts, we never received an email saying that our testing account was under attack. On the other hand, our security advisories are always received with great surprise. So we tend to assume that our activities were unnoticed. And this is not how it is supposed to be. Logging and monitoring should help organizations to mitigate the risk and act on a timely fashion. It's time to wrap up this talk. We're gonna share our final thoughts. We definitely think that APIs are juicy. They tend to handle huge amounts of data, and they also leak some of that data. We still see lots of user authentication issues. They were common on traditional web applications, and they are still common on APIs. The same way, we see a lot of authorization issues. The API scope tends to be big and complex, and authorization is not an easy task. We have been watching the rising of GraphQL. We still see REST APIs, as well as XML or JSON-RPC APIs. But the number of GraphQL is increasing rapidly. And GraphQL is a very recent technology, and it brings specific security concerns. Finally, from our experience, organizations are still taking too long to answer and fix vulnerabilities. And this is something that we will keep working to improve with our research and responsible disclosure. 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. We are available to answer your questions. Feel free to reach us on Twitter, and keep safe and strong.