# Facebook exploit – Confirm website visitor identities

Facebook AJAX endpoint omitted JSON magic prefix when __user matched logged-in UID, letting any page confirm visitor identity via script onload/onerror at ~500 IDs/sec.

- Payout: $1,000
- Severity: medium
- Program: Meta / Facebook
- Credited: Tom Anthony
- Disclosed: 2019-03-04
- Write-up quality: 8/10
- Original: http://www.tomanthony.co.uk/blog/facebook-bug-confirm-user-identities/
- Library page: https://bugbountylibrary.com/r/blog%3Atomanthony-co-uk-blog-facebook-bug-confirm-user-identities
- Tags: domain:web impact:data-leak kind:bounty platform:blog sev:medium tech:rest technique:recon technique:source-review vuln:info-disclosure vuln:xs-leak

**Target:** Facebook AJAX pagelet endpoint (TimelineEntStoryActivityLogPagelet) with __user parameter
**Root cause:** Endpoint returned unprefixed pure JSON when the __user URL parameter matched the logged-in user, but added the magic prefix only on mismatch; combined with content-type differences this produced distinguishable script load/error behavior.
**Steps:**
1. Enumerate Facebook AJAX endpoints lacking access-control-allow-origin and magic-prefix protections that accept a UID in the URL.
2. Find `TimelineEntStoryActivityLogPagelet?...&__user=XXXXXXXX&__a=1` which returns pure JSON when __user matches, prefixed JSON otherwise.
3. Since CORS blocks XHR, load the endpoint as `<script src=...>`; onload fires on match, onerror on mismatch (content-type differs).
4. Generate many script tags for candidate IDs; HTTP2 multiplexing allows ~400-500 IDs/sec with no rate limiting.
5. Detect match/mismatch via onload/onerror callbacks to confirm the visitor's Facebook UID.
**How found:** After finding a Google search bug, author hunted for ways to identify FB users on third-party sites. Surveyed AJAX endpoints for missing CORS/magic-prefix protections and UID-in-URL; also checked images and 301/302s. Found one endpoint with an inconsistency: prefix only on UID mismatch. CORS blocked XHR, so pivoted to script-tag loading and observed differing onload/onerror behavior.
**Exploitation:** A malicious page embeds the endpoint as script tags for a list of known UIDs; onload/onerror distinguishes the logged-in user's ID, enabling cross-site identification of visitors against a harvested ID list.
**Escalation:** None beyond identification; author notes repressive regimes or corporate IP ranges could narrow candidate lists, and Cambridge Analytica-affected users' IDs are already known.
**Insight:** When CORS blocks XHR, test the same endpoint as a <script> src: differing content-type or prefixing between match/mismatch states yields an onload/onerror oracle. Look for endpoints that apply anti-hijacking prefixes conditionally rather than uniformly.
