← All talks

Examining Access Control Vulnerabilities in GraphQL - A Feeld Case Study - Bogdan Tiron

BSides Bournemouth26:5424 viewsPublished 2025-09Watch on YouTube ↗
About this talk
🎀 Talk Title: Examining Access Control Vulnerabilities in GraphQL - A Feeld Case Study πŸ‘€ Speaker: Bogdan Tiron πŸ“ Abstract: This talk explores the importance of implementing robust access controls in GraphQL and REST APIs and the severe consequences when these controls are not properly enforced. GraphQL, a flexible data query language, allows clients to request exactly the data they need, but without proper access control mechanisms, sensitive data can be easily exposed. Using the Feeld dating app as a case study, we will dive into a critical security review of how the lack of access controls in GraphQL and REST endpoints led to the exposure of users' personal data, including sensitive photos, videos and private messages. This session will highlight common access control vulnerabilities in GraphQL and REST implementations , real-world examples of security lapses, their impact and remediation. βš“ This talk was recorded live at BSides Bournemouth 2025 on 16th August 2025 β€” a community-driven cybersecurity conference bringing together researchers, practitioners, and enthusiasts to share knowledge, skills, and ideas. 🌐 Learn more: https://bsides-bournemouth.org/ πŸ’Ό Connect with us: https://www.linkedin.com/company/bsid... πŸ“Ί Stay tuned for more talks from the event, and don’t forget to subscribe for updates!
Show transcript [en]

Hi everyone. I'll be I'll be talking about access controls vulnerabilities in GraphQL and this will be a fieldy case study on uh on data exposure. Uh who am I? Senior pentestert for brbridge uh accredititations in uh pentesting dev sec ops and GCP security uh more than 10 years of experience in security and uh in past history I've been working mostly for banks and in the gambling industry. What is this talk about? So this talk is about the importance of access controls in API uh security. According to was top 10 for APIs. Uh the the category is on first place and is known as Sabola broken object level authorization category and the for web apps it is also

on first place uh and is known as broken access controls category. So as you can see the access controls are for APIs and web apps really important. If we continue okay so we will be talking about the field mobile app and what is field mobile app. It launched in 2014 and it launched under the name of trender as the name implies it was focused on uh threesomes. In 2016 it got renamed to field D because of a naming conflict in their trender. they uh renamed to field and became more open to the idea of dating. So it's a dating app just like uh others Tinder, Bumble, etc. where you can filter by distance, by age, by gender. There are more than 10

genders, couples, and by location. And for premium users, you can also search by the type of kink uh you are interested in uh or the type of relationship you are interested in. On Android Play Store, it has more than 1 million downloads. Okay, let's discover the app and its menu and see uh what it does exactly. So, we have the first menu which is discover profiles menu where you can uh see the name of the person, photos, a short bio and what the person is interested in. Uh then we have the second menu uh who liked you menu where as a basic user you only see the name and the blurred photos. That's it. You need the premium

subscription. Then for the third menu, messages, you have the messages with the person you match with. And last menu, my uh profile menu where you have your own profile and you can buy the premium membership. Okay. So what we will be discussing today? We will be discussing eight vulnerabilities related to access controls. uh first one is a broken object level uh broken object property level authorization category and all the other uh seven are bola category. What's the difference between the two of them? one uh it uh it's about access to another user's ID which you should not have access to and the other is about access to a property within a user object that you you should have access

to that uh uh object but not to that specific property within the object. So that's the subtle difference between this but all are related to access controls. Let's go to the next one. Okay, first first vulnerability disclosure of profile information to nonpremium users. So as I mentioned before, as you can see as a basic user, you only have uh in the who liked you menu, you uh see only the name of the person who liked you and their brother photos. However, as a premium user, you will get all the information. So let's see how we can uh exploit this issue and see all the information as a basic user. So uh one back. Okay. Uh so if we go to the likes

menu to see who liked us, we intercept the request. We will find the graphql request uh with the name uh the with the name likes query. Yes. And uh if we go back uh yes we will see details in the response about the person who liked us. For example, in this case we will have user Sam uh Sam liked us. We didn't like Sam yet. Uh and we'll have the photos of the user Sam uh like in this case picture URL. So if we copy this picture URL and we paste it in the browser, we will have the photo of Sam. I'll go back one sec. And this is the photo of Sam which corresponds to this

one. So we've managed to get details about the user who liked a Sam uh as a basic user just by intercepting the the response. And here we have lots of details about Sam. Unfortunately, the quality it's a little bit uh uh bad in here. Uh so we can see uh more details about SAM, sexuality, uh location, when was last seen, uh if it's a premium user or not, gender, how far is she from us? Uh but one important parameter about Sam is stream user ID and we will this stream user ID is unique to every user and we will use this value to access their messages. So let's go to the next uh issue read other people messages. So

this is uh where we will use this uh important uh parameter uh stream user ID to read other people's messages. So uh we go to discover profile menu intercept the graphical request uh with operation name discover profiles. uh we get the stream user ID of a random uh uh user in this case u uh one second um in this case B4F uh which belongs to user claw uh yes perfect next one please um and now we go to messages uh menu we intercept the request to slash channels endpoint point. Uh uh next one. And here we from the request we uh leave only the members in parameter and we add the um stream user ID of our victim claw

and we see the messages of our user claw. uh the first one saying hi claw and the next one if we search by text we will see that claw has 92 uh messages sent and received. So this is how we read other people's messages. Okay, building upon these two issues uh we get to vulnerability number three which is unauthenticated access to other people's attachments photos and videos. This is probably the most interesting one in the in uh this research. So we can send photos and videos in the app and as you can imagine being a sensitive app at one point they came with a decision let's send photos and videos that delete themselves. So the photos

can be replayable or time limited and the videos can be replayable and play once only and as attacker we can get all of them unauthenticated. So let's see how we did that now to give you the final result the high level uh picture uh so for replayable photos the photo first gets uh uploaded here on the third party and then it will made it will be made available to two other endpoints uh here being the photo ID and the two endpoints the sender and the receiver grid. But because the back end only checks the photo ID here you can just leave an X or any character that you want because it only the back end only

validates the photo ID. So this is for the replayable photos. And then the next one for time limited photo again the photo first gets uploaded uh here on the third party and then it will be made available to the two endpoints. But this time it will check the sender and the receivers's grid. So we will need this uh grids uh the once the receiver receives the photo this uh this endpoint will return 404 uh it will delete itself. So as an attacker when we go uh we exploit it from the end to the uh from the bottom to the top. we will need uh the sender's uh URL to get the photo authenticated and then

unauthenticated we will leak we will need to leak this URL which is part of a feature of the of the function of the app. So let's reproduce the issue and see how we did that. Okay. So um let's uh upload the replayable photo. We go to the chat. We upload the uh the photo. Uh there will be um yes uh request to apicloudinary.com to upload the photo. Uh next one. Okay. Then uh will be a graphical request upload chat attachment uh which I suspect this request will be will make the photo available to the other two endpoints. Next one. And uh the generated photo ID will be sent in the chat and this is how it will

show in the in the chat with attachments saying there there will be an image with this photo ID and it is replayable. Okay. So now let's uh become the attacker. We will uh read our victim's messages uh using their stream user ID and we will see in the messages of our victim an attachment section saying uh the image ID which we will need to access the image ID and that the image is replayable. So we will uh build the URL using the attachment ID from the response uh and use an X as a sender or receiver because it doesn't matter and we will get the photo authenticated. So this is uh the attach the image uh ID

saying replayable and then if we want to get it authenticated as part of the app there's a an endpoint uh as normal uh functionality of the app where we add v uh v1 in front of the of the endpoint and we get the full URL from the third party where we get it unauthenticated and if we copy this URL in the browser we will get unauthenticated access to the uh photo which uh in this case this is one from uh my office. So we just needed a v1 in front of the URL to get the URL to the third party. Now for the uh sensitive um um for the time limited photos there are two main differences compared to the

previous process. uh this time for timesensitive photos there will be an extra parameter saying uh 15,000 milliseconds or 15 seconds and in this case uh they will check on the back end the profile ID of the sender u uh uh the profile ID grid value of the sender so we will need that value let's reproduce the issue again uh let's upload the photo there will be a request apicloudinary.com to upload the photo. Yes. Um then the graphical request to upload chat attachment uh saying that the visibility milliseconds will be 15,000 meaning 15 seconds for this photo. Yes. And now as an attacker we read our victim messages using their stream user ID and we will see the attachment

section uh showing us the photo ID and that the this photo is uh view once only for 15 seconds. Okay. So to retrieve the image we will need the uh profile ID grid of our victim. Uh so there are two URLs to get the photo authenticated. One is from the uh receiver. However, once the receiver sees the photo, uh the photo will return 404 not found. So then the other option is to get the URL of the sender. Uh so we'll need the sender's profile ID grid uh to to access the photo. Okay. And then once we got that photo authenticated, we just prepared V1 as we did previously in order to leak the URL

to the third party where it was initially uploaded uh to get access to the photo unauthenticated. Once uh once we did that, we get the URL, we access it unauthenticated uh and uh we we have access to it. Uh in case we leak the photo ID from the third party, the only thing random uh in it are eight characters. So depending on how sensitive it is, you might want to brute force this eight characters. Okay. for uh for photos uh for videos sorry the process is easier uh there is one request to upload uh the photo which will return you the URL to stream iocdn where the video was uh uh uploaded. This URL will be pasted uh in the chat

will be sent in the chat saying uh type video duration zero. So the attachment will be of type video. Yeah. Then as an attacker we use the victim stream user ID. We read their messages. We see an attachment section saying type a video. The URL of the video which uh the video will be replayable. As part of the URL of the video, there will be a special character back slashu000026, which is the equivalent of the amperson character. So, we copy this URL and replace back/000026 with the amperson character. And once we did that and we put the UR in the browser, we will get unauthenticated access to the video. And then for the play once only video,

the process is similar. We upload the video. we get back the URL just that this time uh when it's sent in the in the chat it will say view once with duration zero for the video which will be reflected back in the response and then again we read the messages of our victim was the attacker using their using a victim stream user ID and we see the URL type video duration zero view once only for the video we replace the back/000026 with the amperson character and once we put it in the browser we should have uh access to the video unauthenticated. So this is uh how to get access to the photos and videos unauthenticated.

Now uh the receiver of the play once video will have no knowledge of the attack. uh he can still see the video but only once and after the video after he sees the video it will say video expired. So this is before and after the receiver see sees the video once. Before it says tap to view and after he tapped a video it expired. However, as an attacker you can see it as many times as you want. So let's do a recap regarding impact. So we know the app launched in 2014 under the name of trender. In 2024, last year I published the research and all and discovered that all the photos and videos were available online without

authentication. Uh we know that on Android it has over 1 million downloads and now all the issues are fixed. Okay, vulnerability number four, uh delete, recover, and edit other people's messages. So we discovered that we can recover other people's messages that were deleted in a chat. Um, in addition, we can edit and delete other people's messages. Uh, in order to do that, we will need the unique message ID value of the message that we want to recover. So, let's uh um drop a message to someone for example, got any plans for tomorrow? Uh, and we will see the ID 8 for this message ID. Uh, so we delete this message uh 8. uh and it will be reflected in the

response 8 got any plans for tomorrow. Now let's become the attacker. We read our victim's messages using their stream user ID and we see that for the 88 message ID uh the text is this message was deleted. So so far everything worked okay. However, if we as the attacker apply again the delete method on this uh message ID 8, we got back the original message got any plans for tomorrow. So all we had is to do as an attacker was just to apply again the delete uh method uh on the same message ID in order to retrieve the original one. [Music] Now to edit the message uh let's uh drop a message. My phone number is 123 uh to

someone. Uh we'll see it reflected in the response. My phone number is 123. Then we read uh uh the messages uh using the victim's message ID. My phone number is 123. Yeah. And uh the victim receives a notification. My phone number is one two three. So so far is okay. Now let's uh modify this uh message as the attacker. My new phone number is 4556. Uh, and we saw it. Uh, uh, we saw it. Yes. Modify. My new phone number is 456. And now uh, if the victim taps on the notification and checks the message, it will say my new phone number is 456 and edited. So all the victim will see extra. it will see this small edited uh

field but has no knowledge regarding who edited if it was the original sender or not. So that was another example of access controls where the attacker modified the the message. Now next uh issue regarding access control update someone else's profile information. So you can update someone else's profile information including name, sexuality, age etc. The endpoint is GraphQL operation name is profile update. So uh we we go to our own profile. We update our own bio to ABCDF. Uh we are logged in as uh user ourself 91F. However, we change the ID to that of a different user. In this case, a random user uh with profile ID ending in 29C. And we see that we will get a 200

okay saying that for the user uh 29C the biography was updated to ABCD. So we managed to update someone else's uh profile uh uh biography. Okay. Another interesting issue regarding access controls uh get a like from any uh user profile. So you could send likes from profile number two to profile number three while being logged in as profile number one. The instance is /graphql and the operation name is profile like. So let's reproduce the issue. We send the normal like which is uh corresponds to the request graphql. So we are logged in as 29c and we send the like from ourselves. So to 9c to uh 91. So we just like someone and it will

be it will be saying sent which worked okay as expected. Now let's reverse. So we are logged in as 9C and we send the like from 91F uh to ourselves and it will say you cannot like a profile you own. Okay then let's send the like to someone else. So we are logged in as 9C and we send the like from 6D3 to 91F and it will say send. So we just managed to control uh who do we send the like and to whom. So we just sent a like from 63. So let's now investigate uh who did we just like our another test account. So let's see who is this 63. So if we

get more information about this 63 account, we see that uh more details about this account saying age 26, imaginary name Annie, uh she liked us, we didn't like her back. Uh and because we have a premium account, we can see uh more details about Annie and indeed uh she liked us. So that was another access control issue. Now vulnerability number seven, send messages in other people's chats even though we are not participant in that chat. Um SL channel/ messenger id/ channel ID slash messages the vulnerable endpoint. Um now um let's read other people's messages using the victim stream user ID. We will find a channel ID in this case ending in zero BDD. And if we send a message to that uh

zerob channel ID uh such as hello from the attacker, it will say 201 created. Okay. So the victim will receive a notification from uh user B which is the attacker. And in this uh u uh window um the victim will see the message hello from the attacker. However, the message takes place between user D and Bogdan. So, the message comes from B. However, uh the attacker can change his name as part of the application because this is a future of the application. Anyone can have any name they want. So, you can impersonate even the victim or the sender if you want. So, okay. And the last vulnerability, view other people's matches. We can check who did

other people match with and their full profile information such as imaginary name, age, photos, uh gender, sexuality. The instance is /graphql operation name chat list query. Okay. So um we go to discover profiles menu. We see the /graphql chat list query operation. Um and we will see in the response that uh if we do that for our own account and we search for imaginary name in the response we have three matches. However, if we change the profile ID to that belonging of a different user we see that uh if we search by imaginary name in the response uh that profile ID will have 45 uh matches on their accounts. So this is another example of access controls where

we can check uh how many matches other accounts have. Okay. So as immediation for this access controls for developers implement authorization checks between users. This must be on the back end and not on the front end. Implement user levels for example basic users and premium users. And based on this user levels implement access controls and uh restrict information to the user based on user level. For dev sec ops people this will be a challenging one to integrate in the C cd pipeline a security tool that does uh this specific check. I am not aware yet of uh such a tool that could do a good job uh on exploit on exploring this sort of uh category issues for CESOS. do

data mapping, identify all personal data your organization collects and inter and and implement uh data protection measures uh such as encryption, access controls and security testing. Uh regarding fines, uh Uber was fined for sending uh drivers data to US from EU and more recently Tik Tok was uh fined as well for sending European data to China. uh remediation. This was a bit u interesting. Uh all the issues have been remediated. However, uh uh according to to the best of my knowledge, it took them six months and after 6 months, we published this blog post. So, it took a bit of time to remediate all these issues. Uh for a full research, you can check our blog post. Uh and then uh this uh

was also uh uh highlighted by the guardian in an article and the slides will be published soon on our GitHub and then a short uh uh okay