Back

The “Ghost Admin” Bypass: Hijacking Meta Portfolios via Persistent Asset Sessions

I recently identified a severe business logic flaw in Meta’s Business Portfolio infrastructure. This is a nightmare for Social Media Agencies because it creates a “Ghost Admin”—a user who is completely invisible to the management team but retains full, high-level control over the entire business.

Long story short: I found a way to stay logged in as a master administrator even after the owner “deletes” you. As long as the Instagram account remains a connected asset, the session stays alive, allowing an attacker to manipulate roles, kill integrations, and hijack financial data from the shadows.

The Real-World Scenario: The Agency Trap

Imagine a Social Media Agency (User A) is hired to manage a brand’s Instagram account. The Agency Admin adds the brand’s Instagram account (User B) into their Business Portfolio as an Asset.

Meta automatically adds a user entry for that account in the “People” list. To keep their internal staff list clean, the Agency Admin immediately removes that auto-generated user from the “People” section. They assume the door is locked. They are wrong.

Why This is Dangerous: Total Portfolio Hijack

  • Shadow Hierarchy: Change existing users’ roles and permissions from within.
  • Asset Sabotage: Disconnect Facebook Pages from Ad Accounts or re-link them to different profiles.
  • Operational Nuking: Permanently remove connected applications (CRMs, lead-gen tools) without being on the staff list.
  • Financial Espionage: Monitor balances and full transaction logs across all Ad Accounts via manual URL manipulation.
  • Campaign Sabotage: Instantly pause all active ad campaigns across any Ad Account with no bulk-unpause option and no audit trail.

How I Verified the Mess (Repro Steps)

Step 1: The Setup
The Agency Admin (User A) added my Instagram account (User B) to their Business Portfolio as an asset.

Step 2: The Deletion
Immediately after, User A went to the “People” section and manually Removed me. I am now invisible in their management list.

Step 3: The Entry
On my device (User B), I logged in to business.facebook.com using my Instagram credentials.

Step 4: The Bug
Despite being “removed” from People, I still had full access to the dashboard because the account was still a “Connected Asset.”

Step 5: Bypassing Management
I navigated directly to the user settings URL:
https://business.facebook.com/latest/settings/business_users/?business_id=PORTFOLIO_ID
I wasn’t on the list, yet I could still edit the roles of other users and change their assigned assets.

Step 6: Asset Manipulation
I went to the “Business Assets” section. I was able to select a Page and disconnect it from its linked profile or assign it to a different Ad Account.

Step 7: Connected Apps Removal
I navigated to Integrations > Connected Apps. I successfully clicked “Remove” on an active third-party app, killing a live business integration.

Step 8: Financial Data Exposure via URL Manipulation
I navigated to Billing & Payments > Accounts. I grabbed the asset, business, and payment IDs directly from the URL browser string and manually requested access to the core billing hub details via this custom URL path:

https://business.facebook.com/billing_hub/payment_activity?asset_id=ID&business_id=ID&payment_account_id=ID

The Result: Full unauthorized access to view the Ad Account balance, billing activity, and historical transaction logs.

Step 9: Campaign Sabotage (Pausing All Ads)
While holding this Ghost Admin session inside the billing infrastructure, I discovered it was also possible to completely pause ALL active campaigns on any Ad Account in the portfolio by firing an internal GraphQL mutation directly:

Endpoint: POST https://business.facebook.com/api/graphql/
Mutation: useBillingPauseCampaignMutation
doc_id: 29537422355905645

Variables:
{
  "input": {
    "payment_account_id": "<AD_ACCOUNT_ID>",
    "business_id": "<BUSINESS_ID>",
    "actor_id": "<ACTOR_ID>",
    "client_mutation_id": "1"
  }
}

Response:
{"data":{"pause_all_active_campaigns_for_ad_account":{"success":true}}}

The Result: All active campaigns on the target Ad Account are immediately paused. There is no bulk-unpause feature built into the platform—each campaign must be manually toggled back on by the business owner. The executing shadow user remains completely missing from the official staff lists with zero footprint in the audit trail.

Resolution and Fix

After discovering the vulnerability, I reported it through Meta’s Bug Bounty Program, providing detailed reproduction steps and a proof-of-concept video. Meta acknowledged the issue and implemented a fix to secure the system.


Subscribe
Notify of
guest
0 Comments
Oldest
Newest Most Voted
Inline Feedbacks
View all comments