Examining Access Control Vulnerabilities In GraphQL - A Field Case Study
Examining Access Control Vulnerabilities In GraphQL - A Field Case Study.
Summary
### Overview In this talk, Bogdan, co-founder and senior pentester at Forbridge, presents a security case study examining access control vulnerabilities discovered in the dating app Feeld (formerly known as 3nder / Trender). The research identified eight access control vulnerabilities spanning GraphQL and REST endpoints—specifically seven Broken Object Level Authorization (BOLA) flaws and one Broken Object Property Level Authorization (BOPLA) flaw. These issues enabled unauthorized access to sensitive user data, interception and manipulation of private communications, and complete tampering with user interactions.
### Key Topics - **OWASP Top 10 Context:** Broken Object Level Authorization (BOLA) ranks as the #1 threat in the OWASP Top 10 API Security, while Broken Access Control holds the #1 spot in the OWASP Top 10 Web Application Security (2021). - **Application Background:** Feeld launched in 2014 as 3nder/Trender before rebranding in 2016 due to trademark conflicts. It operates as an alternative dating app with over 1 million Android downloads, catering to specific dating preferences, relationship types, and kink exploration. - **Access Control Breakdown:** The app relied heavily on client-side restrictions and predictable identifiers, lacking adequate server-side authorization checks on both GraphQL queries/mutations and RESTful endpoints.
### Technical Details The presentation details eight distinct vulnerabilities discovered within Feeld:
1. **Profile Data Disclosure to Non-Premium Users:** Basic users typically see blurred profile pictures and limited profile data for users who liked them. However, by intercepting the `likesQuery` GraphQL operation in a proxy (Burp Suite), unblurred image URLs hosted on Cloudinary (`cloudinary.com`) and full profile details—including unique `stream_user_id` values—are returned directly in the response unauthenticated. 2. **Reading Private Messages:** Using a victim's `stream_user_id` harvested from the discovery menu, an attacker could supply this ID to the `/channels` endpoint, removing other parameters, to retrieve the victim's complete private chat history. 3. **Accessing Sensitive Media Attachments:** While the app claimed to offer time-limited (15-second) and play-once media, media files were hosted on external CDNs (`api.cloudinary.com` and `streamiocdn.com`). Attackers could leak the direct CDN URLs authenticated or unauthenticated: - For replayable images, the backend chat attachment endpoint verified only that an image ID existed, ignoring user identity. Prepending `/v1` to the path exposed the unauthenticated Cloudinary URL directly. - For time-limited images (using `visibility_milliseconds: 15000`), attackers could retrieve media via the sender profile ID even after expiration on the receiver's end, or prepend `/v1` to leak the original URL. - For videos, direct CDN links in attachment JSON payloads contained unicode-escaped ampersands (`\u0026`), which when unescaped allowed unauthenticated viewing regardless of "play once" limitations. 4. **Deleting, Recovering, and Editing Other People's Messages:** Using a target message ID: - Sending an HTTP `DELETE` to `/messages/{message_id}` on an already deleted message recovered the original deleted text. - Sending an HTTP `PUT` request with a modified body allowed an attacker to overwrite any user's message with an "edited" flag, obscuring the author's true identity. 5. **Updating Other Users' Profile Information:** The GraphQL mutation `profileUpdate` accepted arbitrary profile IDs, allowing an authenticated user to alter the name, bio, sexuality, and age of other profiles. 6. **Forging Profile Likes:** The GraphQL `profileLike` operation permitted an attacker logged into Account A to forge a like between Account B and Account C, manipulating user match systems. 7. **Injecting Messages into Third-Party Chats:** Attackers could POST messages to `/channels/messaging/{channel_id}/message` without being chat participants. Combined with Feeld's non-unique display names, attackers could trivially impersonate participants. 8. **Viewing Other Users' Matches:** Changing the profile ID parameter in the `chatListQuery` GraphQL operation returned the full match list and associated profile details of any targeted victim.
### Takeaways - **Developers:** Enforce authorization and role-based access controls strictly on the back end, never relying on the client application to obscure or filter data. Restrict API responses strictly to data appropriate for the requester's tier. - **DevSecOps:** Incorporate automated API security checks into CI/CD pipelines, noting that manual testing remains essential because automated scanners often struggle to discern access control boundaries among similar GUIDs. - **CISOs & Leadership:** Perform comprehensive data mapping to locate all collected personal data, apply robust encryption and testing, and monitor third-party storage to prevent regulatory breaches (such as GDPR enforcement actions). - **Disclosure:** Despite the simplicity of the root causes, Feeld took over six months to remediate all reported issues before public disclosure by the researchers and coverage by outlets like The Guardian.
Related talks
Black Hat·56 min
Engineers explore architecture and security mechanisms for A Retrospective Case Study of VMware Guest-to-Host Escape Vulnerabilities.
HITCON·36 min
Analysts investigate attack surfaces and defenses concerning 2021 - The Great Escapes : A Case Study Of VM Escape & EoP Vulnerabilities.
Mobile Village·25 min
Bogdan Tiron
Examines authorization and access control vulnerabilities in GraphQL and REST APIs, using the Feeld dating app data leak as a case study in data exposure.


