# Create post on any Facebook page

Creative Hub's share-preview workflow skipped Page role checks, letting an attacker create invisible unlisted posts on any Facebook Page.

- Payout: $30,000
- Severity: medium
- Program: Meta / Facebook
- Credited: Pouya Darabi
- Disclosed: 2021-01-08
- Write-up quality: 7/10
- Original: https://www.darabi.me/2020/12/create-invisible-post-on-any-facebook.html
- Library page: https://bugbountylibrary.com/r/blog%3Adarabi-me-2020-12-create-invisible-post-on-any-facebook-html
- Tags: domain:web impact:integrity kind:bounty platform:blog sev:medium tech:graphql technique:chained technique:incomplete-fix vuln:access-control vuln:auth-bypass vuln:idor

**Target:** Creative Hub GraphQL mockup-save and ad-previewer endpoints
**Root cause:** The share-preview path generated a preview post on the selected Page without verifying the user held an advertiser role on that Page, unlike the normal preview flow.
**Steps:**
1. Intercept the Creative Hub mockup-save GraphQL request and change `page_id` to a target Page ID.
2. Save the mockup; request is accepted without authorization error.
3. Click Share to get `https://www.facebook.com/ads/previewer/__PREVIEW_KEY__`.
4. Query ad-preview endpoints to retrieve the generated `post_id` for the target Page.
5. Bypass: call `AsyncRequest.post('/ads/previewer/notify_mobile/__PREVIEW_KEY__', {})` to regenerate the preview without the Page permission check.
**How found:** Testing the mockup preview workflow, the researcher intercepted the save request and swapped page_id, noticing it saved without an authz error; comparing the normal preview flow (which enforced a role check) against the share-preview flow revealed the missing check.
**Exploitation:** Attacker with any Creative Hub access modifies page_id in the save request, triggers preview generation via the share page (or notify_mobile endpoint), then reads the post_id from previewer endpoints, yielding an unlisted post on a Page they have no role on.
**Escalation:** After the initial fix, the researcher pivoted to the Send to Mobile workflow calling `/ads/previewer/notify_mobile/__PREVIEW_KEY__`, which regenerated the preview without the authorization check, reproducing the bug.
**Insight:** When a feature has multiple entry points to the same privileged action (normal preview vs share vs notify_mobile), test each path separately for the authz check — fixes often cover only the reported endpoint, leaving sibling workflows unprotected.
