# Able to see Twitter Circle tweets due to improper access control on the "FavoriteTweet" endpoint

FavoriteTweet GraphQL endpoint let non-members like Twitter Circle tweets, and the data archive export then revealed the private tweet content.

- Payout: hidden
- Severity: medium
- Program: X / xAI
- Found by: bugra
- Disclosed: 2024-03-01
- Write-up quality: 7/10
- Original: https://hackerone.com/reports/1694304
- Library page: https://bugbountylibrary.com/r/h1%3A1694304
- Tags: area:web domain:web impact:data-leak kind:bounty platform:hackerone sev:medium tech:graphql technique:chained vuln:access-control vuln:idor vuln:info-disclosure

**Target:** FavoriteTweet GraphQL endpoint and download_your_data archive export
**Root cause:** The FavoriteTweet endpoint failed to verify the liker was a member of the tweet's Twitter Circle, and the data-export pipeline rendered liked tweet content without re-checking Circle visibility.
**Steps:**
1. Proxy a normal like; observe `POST` to `FavoriteTweet` GraphQL endpoint with `tweet_id`.
2. Replace `tweet_id` with a Twitter Circle tweet ID not visible to the attacker; response returns `200 OK`.
3. Request data archive at `https://twitter.com/settings/download_your_data` and wait for email.
4. Open the archive's HTML file or `data/like.js`; the private Circle tweet content is present.
**How found:** Noticed the like request accepted an arbitrary tweet_id; confirmed liking worked but UI hid the tweet, then hypothesized the data-export feature would surface liked tweet content and tested it.
**Exploitation:** Attacker likes an out-of-circle tweet via the FavoriteTweet endpoint, then triggers a data export; the archive's like.js/HTML includes the full private tweet text, disclosing Circle-only content.
**Insight:** When an authorization check is missing on a write action, look for secondary read surfaces (data exports, archives, activity feeds, notifications) that render the written object without re-checking visibility.
