# Twitter ID exposure via error-based side-channel attack

JSON endpoint returned 403 for mismatched user IDs but 200 for the logged-in user, letting a malicious site confirm a visitor's Twitter identity via script onload/onerror.

- Payout: $1,470
- Severity: medium
- Program: X / xAI
- Credited: terjanq
- Disclosed: 2019-05-16
- Write-up quality: 6/10
- Original: https://hackerone.com/reports/505424
- Library page: https://bugbountylibrary.com/r/h1%3A505424
- Tags: domain:web impact:pii-leak kind:bounty platform:hackerone sev:medium tech:rest technique:js-analysis vuln:info-disclosure vuln:xs-leak

**Target:** developer.twitter.com API endpoint /api/users/{USER_ID}/client-applications.json
**Root cause:** The endpoint's response status differed based on whether the requested USER_ID matched the logged-in session user, and it was loadable cross-origin as a script, leaking the match via onload/onerror.
**Steps:**
1. Attacker hosts a page with JS that creates a `<script>` element.
2. Set `script.src = https://developer.twitter.com/api/users/${id}/client-applications.json` for a candidate ID.
3. Attach `script.onload` (ID match) and `script.onerror` (ID mismatch) handlers.
4. Append to document.head; observe which handler fires to confirm the victim's ID.
**How found:** Noticed that developer tools load a user-specific JSON resource (client-applications.json) keyed by USER_ID, and that a mismatched ID returns a 403 error while a matching one returns 200 — a status-code oracle usable cross-origin via script tags.
**Exploitation:** Victim visits attacker-controlled site while logged into Twitter; the injected script tag requests the endpoint with a guessed USER_ID. A 403 (mismatch) triggers onerror, a 200 (match) triggers onload, revealing whether the visitor is the targeted user.
**Insight:** Look for authenticated JSON/API endpoints whose HTTP status (200 vs 403) varies by whether the requested resource ID equals the session user; such status oracles are readable cross-origin via `<script>` onload/onerror even without CORS, enabling login/identity confirmation.
