# Hacking Facebook Pages

Omitting the business parameter on the Graph userpermissions endpoint let any app with manage_pages add itself as page admin and remove the real owner.

- Payout: $2,500
- Severity: high
- Program: Meta / Facebook
- Credited: Laxman Muthiyah
- Disclosed: 2015-08-26
- Write-up quality: 6/10
- Original: https://thezerohack.com/hacking-facebook-pages
- Library page: https://bugbountylibrary.com/r/blog%3Athezerohack-com-hacking-facebook-pages
- Tags: domain:api impact:ato impact:integrity kind:bounty platform:blog sev:high tech:rest technique:param-pollution vuln:access-control vuln:auth-bypass vuln:privilege-escalation

**Target:** Graph API /<page_id>/userpermissions endpoint
**Root cause:** The userpermissions endpoint validated the business parameter only when present; dropping it bypassed the restriction that third-party apps cannot add/modify page admin roles, falling back to plain manage_pages permission.
**Steps:**
1. Obtain an app access token for a third-party app holding manage_pages on the victim's page.
2. Send `POST /<page_id>/userpermissions` with body `role=MANAGER&user=<target_user_id>&business=<business_id>&access_token=<token>` to confirm business-page behavior.
3. Remove the `business` parameter: `role=MANAGER&user=<target_user_id>&access_token=<token>`; response `true` adds target as admin.
4. Send `DELETE /<page_id>/userpermissions` with `user=<victim_user_id>&access_token=<token>` to remove the legitimate admin.
**How found:** Author knew the endpoint allowed business page admin role changes with a business parameter; tested removing the business parameter and observed no error, revealing the restriction was bypassed for non-business pages.
**Exploitation:** Any third-party app with manage_pages permission on a page could, via the app access token, add an attacker-controlled user as MANAGER and delete the real admin, permanently locking the owner out of the page.
**Insight:** When an API gates a privileged action behind a scoping parameter (business/org/tenant), try omitting that parameter entirely — validation often only runs when the scope is supplied, silently falling back to weaker permission checks.
