How the attack works
An attacker sends an unauthenticated POST to /mcp invoking the get_ad_accounts tool. The server's auth middleware calls the next handler without rejecting the missing credentials, so the handler falls back to a server-side META_ACCESS_TOKEN environment variable. That token is attached to the outgoing Graph API request as an access_token parameter. If the Graph API call fails, the server serializes the raw request URL, token included, into the JSON-RPC error response, handing the attacker a working Facebook access token.
Why it matters
Anyone who can reach the MCP endpoint can steal the operator's Meta/Facebook access token and use it to read or manage the associated ad accounts, without ever authenticating to the MCP server itself.
What you can do
- Upgrade meta-ads-mcp past version 1.0.108 once a patched release is available, or restrict network access to the /mcp endpoint until then.
- Do not rely on a shared META_ACCESS_TOKEN environment variable for authorization; require per-request Authorization headers for tool calls.
- Audit server logs and error responses for request URLs containing access_token and rotate any Meta access token that may have been exposed.
- Put the MCP server behind network-level access controls (VPN, allowlist, or gateway auth) so it cannot be reached directly from the internet.
Known benign look-alikes
- An authenticated meta-ads-mcp client legitimately calling get_ad_accounts with a per-request Authorization header (not relying on the env-var fallback).
- Documentation or advisory text that names get_ad_accounts or META_ACCESS_TOKEN without an actual JSON-RPC tools/call payload or a leaked request_url.
- A Graph API integration that references graph.facebook.com/me/adaccounts in code without exposing access_token in a response body.