# Facebook’s Burglary Shopping List

Facebook Marketplace GraphQL returned exact seller lat/long and full postcode to unauthenticated users, defeating the advertised location fuzzing.

- Payout: unconfirmed
- Severity: medium
- Program: Meta / Facebook
- Credited: John Moss
- Disclosed: 2019-04-23
- Write-up quality: 6/10
- Original: https://www.7elements.co.uk/resources/blog/facebooks-burglary-shopping-list/
- Library page: https://bugbountylibrary.com/r/blog%3A7elements-co-uk-resources-blog-facebooks-burglary-shopping-list
- Tags: domain:web3 impact:pii-leak kind:bounty platform:blog sev:medium tech:graphql technique:js-analysis vuln:info-disclosure

**Target:** GraphQL endpoint facebook.com/api/graphql for Marketplace adverts
**Root cause:** The mobile-app-created advert stored the exact pinned coordinates and full postcode, and the GraphQL advert response returned them verbatim to unauthenticated viewers instead of fuzzing/snapping to a generic location as the web UI did.
**Steps:**
1. Browse a Marketplace advert (e.g. bicycles) unauthenticated and capture the `facebook.com/api/graphql` request.
2. Inspect the JSON response `location` object: `latitude`, `longitude`, `reverse_geocode_detailed.postal_code` (e.g. NE2 2DS).
3. Create own advert via mobile app pinning a known exact address to confirm the returned coords match the pin.
4. Compare with web app, which cannot drill below nearest suburb, confirming mobile-only precision leak.
**How found:** While investigating scraping Marketplace for stolen-goods recovery, noticed JSON location data looked more specific than the fuzzed location shown in the UI; created own advert to verify the exact pin was leaked.
**Exploitation:** Unauthenticated attacker reads the GraphQL advert response to obtain exact lat/long and full postcode of high-value listings (e.g. a £7,000 bike), combined with seller's full name to locate the address for theft.
**Insight:** Compare API responses against what the UI displays: privacy fuzzing applied client-side or in one client (web) is often absent in another client's (mobile) GraphQL response, so diff the raw JSON against the rendered value.
