WEBVTT

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:37.160
We've got two speakers this time.

00:37.160 --> 00:39.860
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: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.

00:54.860 --> 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.

01:04.100 --> 01:12.760
Paulo, since his first OWASP local event back in 2010, has been active in the community, contributing to several OWASP projects.

01:12.760 --> 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.

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:43.480
Hello everyone and welcome to the API and Security Top 10, the guided tour to the wild wild world.

01:43.580 --> 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.

01:58.320 --> 01:59.860
So, thank you.

02:00.160 --> 02:02.000
Let's start.

02:02.000 --> 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.

02:18.620 --> 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.

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: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.

03:32.540 --> 03:39.880
Some of my work you can already see on TechCrunch, 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: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.

04:03.820 --> 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.

04:14.860 --> 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.

04:22.100 --> 04:28.860
Right now, I do ethical hacking and security research, and since 2010, I'm a regular OWASP volunteer.

04:30.520 --> 04:39.820
Currently, I'm the OWASP Go Secure Coding Practices project co-leader, 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:59.320
Hacking systems without permission is crime, 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:31.260
In fact, you can think about APIs this way, 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: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.

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: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.

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:15.860
You may have already heard about OWASP.

07:15.860 --> 07:23.280
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:46.020
We should learn from past mistakes and R.

07:46.020 --> 07:55.080
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: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.

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: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.

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:39.620
Findings.

11:39.640 --> 11:41.440
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:12.660
But note that both requests were anonymous.

14:12.660 --> 14:15.640
There was no authentication nor authorization.

14:16.040 --> 14:18.860
I think this was a good warm-up.

14:18.860 --> 14:21.460
We can continue with David.

14:23.740 --> 14:25.420
Broken user authentication.

14:25.420 --> 14:28.520
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: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.

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: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.

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: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.

17:22.590 --> 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.

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: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.

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: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.

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: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.

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:05.400
You need to make serious.

23:05.400 --> 23:06.640
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:49.170
It's really a bunch of nothing.

25:49.170 --> 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.

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:15.990
Okay, so stack trace on an handled Java exception.

26:15.990 --> 26:21.200
So, this type of vulnerability is like boring, moving along.

26:21.590 --> 26:25.030
Another stack trace, but this time with more style.

26:25.030 --> 26:27.220
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:58.690
Guess what?

27:58.690 --> 27:59.710
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: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.

28:21.710 --> 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.

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:49.810
So, after a while and checking the burp proxy logs, 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: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.

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: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.

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: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.

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: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.

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: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.

32:37.310 --> 32:45.510
And when it triggers, it will post the payload on the discussion part.

32:45.510 --> 32:57.590
And when the FunkyCat goes to his page and refreshes the meetup group, 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: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.

33:38.860 --> 33:48.640
Either they're not producing enough logging, logs have not enough details, 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.

