MCP Confused Deputy and Token Passthrough: Agent OAuth Authorization State Attacks
MCP confused deputy and token passthrough target the OAuth state an MCP server holds on an agent's behalf: a static client ID and consent cookie an attacker can ride to steal an authorization code, or an access token accepted and forwarded downstream without checking who it was actually issued for. Covers the protocol's own MUST-NOT requirements, the CVE-2026-48039 Meta Ads MCP token leak, and Asana's 2025 cross-tenant MCP incident, with detection and containment that does not require disabling OAuth-backed tools.
- Target
- Tool & Environment State
- Persistence
- Session to Shared-System
- Control
- Prevent, Detect, Contain, Recover
- Status
- SSA Working Term
MCP confused deputy and token passthrough are two related, protocol-documented failure modes in how an MCP (Model Context Protocol) server handles the OAuth credentials it holds so an agent can call a third-party API on a user's behalf. The confused deputy variant lets an attacker steal an authorization code by exploiting a static client ID and a browser's leftover consent cookie, no token theft required. The token passthrough variant is a server accepting and forwarding an access token that was never issued for it, skipping the audience check that keeps one service's token from working as another service's credential. Both fail at the same point: the moment an MCP server, acting as an intermediary with its own standing trust to a downstream API, stops verifying whose authority a request is actually carrying.
What it is
The defining object is the OAuth authorization state an MCP server manages on an agent's behalf: the client ID it uses to talk to a third-party authorization server, the consent state that server remembers for that client ID, and the access token it receives from an MCP client and may forward downstream. The defining cause, for the confused deputy variant, is an MCP proxy server using one static, unchanging client ID for every MCP client that connects to it, combined with a third-party authorization server that sets a browser cookie to remember consent for that client ID rather than for the individual end user. The defining cause for token passthrough is simpler: a server that does not check the audience claim on an incoming token before trusting it or relaying it to another API. The defining consequence in both cases is that the MCP server, which the downstream API implicitly trusts as a single well-known caller, ends up acting with authority a specific request never actually earned.
This differs from MCP tool poisoning in what state gets attacked. Tool poisoning targets the tool description or tool-call result the agent's model reads as instruction-bearing content. This entry targets the authorization plumbing underneath the tool call, the OAuth handshake and token that decide whether the call is even permitted, which is invisible to the model's own reasoning and fails independently of whether any tool description was ever poisoned.
What it is not
- A tool description or tool-call result carrying hidden instructions, covered by MCP tool poisoning, where the failure is in what the model reads, not in the OAuth handshake underneath it.
- Identity spoofing at the discovery layer of a different protocol, covered by agent card poisoning, which targets the A2A Agent Card a client fetches before any session starts rather than the token flow an already-connected MCP client uses against a downstream API.
- A leaked API key or credential sitting in a plaintext config file with no OAuth flow or proxy involved, which is a broader secrets-management problem, not specific to this entry's mechanism.
- A user knowingly granting an agent broad OAuth scopes they later regret; this entry covers the protocol handing over authority the user never actually consented to, not a consent decision made in full knowledge.
- Reproducible exploit code or a working forgery recipe against a named vendor's live MCP deployment.
In scope
- MCP proxy servers using a static client ID with a third-party authorization server that sets consent cookies, letting an attacker's dynamically registered client ride an existing cookie to steal an authorization code.
- MCP servers that accept an access token without validating its audience claim, letting a token issued for one service function as a credential for another.
- MCP servers that forward an unmodified client-supplied token to a downstream API rather than exchanging it for a token scoped to their own identity.
- Ambient credential fallback, where a server that receives no per-request token substitutes a standing environment credential and then leaks that credential through an error path.
- Defensive controls for per-client consent, audience validation, token exchange, and scope minimization on the MCP authorization boundary specifically.
Target state and trust boundaries
The target state is the OAuth authorization state an MCP server manages between an MCP client and a downstream third-party API: which client ID it presents, what consent decision it has on file, and which access token it is currently honoring. The trust boundary that fails is the assumption, on the part of the third-party authorization server, that a request carrying the MCP proxy's client ID and a valid consent cookie represents one already-approved relationship, when in an OAuth proxy architecture that cookie is shared across every MCP client that has ever registered against the same static ID.
MCP's own specification treats this as a named class of vulnerability rather than a hypothetical. Its security best-practices document defines the "MCP Proxy Server" as an MCP server that "offers MCP features while delegating operations and acting as a single OAuth client to the third-party API server," and states plainly that this attack becomes possible when a proxy server uses a static client ID, allows MCP clients to dynamically register, and the third-party authorization server sets a consent cookie after the first authorization (Model Context Protocol, Security Best Practices, 2026-07-28 revision). The same document separately defines token passthrough as "an anti-pattern where an MCP server accepts tokens from an MCP client without validating that the tokens were properly issued to the MCP server and passes them through to the downstream API," and states the requirement without qualification: "MCP servers MUST NOT accept any tokens that were not explicitly issued for the MCP server."
What the research establishes
The specification itself documents the confused deputy attack chain step by step: a user completes a legitimate authorization flow through the MCP proxy, the third-party authorization server sets a consent cookie scoped to the proxy's static client ID, an attacker later sends the user a link carrying a maliciously registered client ID and an attacker-controlled redirect URI, the browser's leftover consent cookie causes the authorization server to skip the consent screen entirely, and the resulting authorization code is redirected straight to the attacker's server rather than back to the legitimate proxy. The specification's own mitigation section requires MCP proxy servers to maintain a per-client consent registry, check it before forwarding to the third-party authorization server, and never persist a state-tracking cookie until after the MCP-level consent screen has been explicitly approved.
The token passthrough half of this pattern produced a documented, CVE-tracked incident in a live MCP server. CVE-2026-48039, affecting the meta-ads-mcp package at versions 1.0.108 and earlier, combines an authentication bypass with an ambient credential leak: the server's AuthInjectionMiddleware.dispatch() forwarded unauthenticated HTTP requests to tool handlers without returning a 401, and when a tool call received no per-request credential it fell back to a standing META_ACCESS_TOKEN environment variable. When a downstream Meta Graph API call then failed, the raw request URL, including that access token as a query parameter, was serialized verbatim into the JSON-RPC error response, handing an unauthenticated caller a long-lived credential for the operator's Meta Ads account. The advisory carries a CVSS score of 9.1, was published 2026-05-20, and was fixed in version 1.0.109 (GitHub Security Advisory GHSA-9gw6-46qc-99vr / CVE-2026-48039). This is a token passthrough failure in spirit rather than the specification's literal audience-mismatch case: the credential that leaked was never bound to the individual caller's request in the first place, so no audience check could have distinguished a legitimate caller from an attacker.
A cross-tenant incident at Asana illustrates the broader intermediary trust problem the confused deputy pattern names. In June 2025, Asana identified and disabled a bug in its MCP server, live since May 1, 2025, that allowed task details, project metadata, comments, and uploaded files belonging to one organization to become visible to users from other organizations; the company estimated roughly 1,000 customers were affected and contacted them directly. Security researchers at Defakto described the underlying architecture as an instance of "the classic confused deputy problem," noting that "any time there's an intermediary (in this case the MCP server) between a client and a server, we have the possibility of a bug that results in elevated privileges for the client" (Defakto Security, What the Asana MCP Bug Reveals About AI Security Gaps, 2025-06-19; Nudge Security, Asana MCP server data exposure incident). Asana's own public account does not specify whether the bug matched the specification's static-client-ID mechanism exactly; what is documented is that an MCP server acting as a single trusted intermediary between many tenants failed to keep one tenant's request from reaching another tenant's data, which is the same class of failure the specification's confused deputy section exists to prevent.
Persistence
A stolen authorization code or forwarded token is not a single-turn event: the code exchanges for an access token the attacker can use until it expires or is revoked, and a consent cookie that enabled the theft can persist in a user's browser across many separate MCP sessions, meaning the vulnerable window outlives any one conversation. Where the MCP server functions as a shared intermediary across multiple tenants, as in the Asana case, a single confused deputy failure can expose data belonging to organizations that never interacted with the attacker at all, which puts this pattern's upper bound at shared-system scope rather than one compromised session.
Detection: observable signs
- An MCP proxy server issuing the same client ID to a third-party authorization server for authorization requests originating from distinct, unrelated MCP clients.
- An authorization flow that completes with no consent screen shown, immediately following a redirect carrying a newly registered client ID and an unfamiliar redirect URI.
- A downstream API call authenticated with a token whose audience claim does not match the MCP server making the call.
- An MCP server's error responses or logs containing a raw access token, API key, or credential value in a URL, header, or JSON-RPC error body.
- Cross-tenant data appearing in one organization's MCP session output with no corresponding request from that organization's own credentials.
Useful telemetry includes a per-client consent audit log distinct from the third-party authorization server's own cookie-based state, audience-claim validation logged as a pass/fail event on every inbound token, and log correlation between the MCP proxy's caller identity and the downstream API's own request logs to catch identity mismatches the proxy's forwarding would otherwise hide.
Defenses, containment, and recovery
The table below is SSA editorial guidance for defenders. It is neither a standard requirement nor a measured effectiveness ranking.
Control | Transition it interrupts | Applicability | Residual risk and verification |
|---|---|---|---|
Per-client consent registry checked before third-party forwarding | An attacker's dynamically registered client riding a legitimate user's leftover consent cookie | Any MCP proxy server acting as a single OAuth client to a third-party authorization server | Only closes the gap if the registry is checked before every forward, not just on first connection; verify by testing a second, distinct client ID against an already-consented user. |
Audience-claim validation on every inbound token | A token issued for one service being accepted as valid for another | Any MCP server that receives bearer tokens from MCP clients | Requires the token format to carry a checkable audience claim (for example per RFC 9068); opaque tokens need an introspection call instead, which some deployments skip for latency reasons. |
Token exchange instead of raw forwarding | A downstream API trusting a passed-through token as if it originated from the MCP server itself | MCP servers that call a downstream API using credentials derived from an inbound client token | Adds an extra network round trip and requires the downstream API to support a token-exchange or delegation flow; not every third-party API offers one. |
No ambient credential fallback for unauthenticated requests | An unauthenticated caller receiving a standing service credential by default when no per-request token is present | Any MCP server configured with an environment-variable or service-account credential as a fallback | Removing the fallback can break legitimate low-friction use cases that relied on it; pair with an explicit 401 response rather than silent denial so failures are visible. |
Error-path credential scrubbing | A token or credential leaking through a serialized request URL or stack trace in an error response | Any MCP server whose error handling reflects request details back to the caller | Scrubbing has to cover every error path, not just the common ones; a single missed serialization point, as in CVE-2026-48039, reintroduces the leak. |
Prevention should treat every inbound token as untrusted until its audience is verified and should never let a static client ID stand in for individual user consent. Detection should log consent and audience-validation outcomes as first-class, queryable events rather than incidental log lines. Containment should revoke the affected client ID's standing trust and force re-consent for every user who authorized through it, since a compromised static client ID cannot be selectively distrusted for one attacker while remaining trusted for legitimate callers. Recovery should treat any data accessed through a confirmed confused deputy or passthrough incident as exposed to whoever held the stolen code or token, not merely to the attacker who was first observed, and should rotate the downstream credentials the proxy held rather than assuming the token's stated expiry was honored.
Boundaries with similar concepts
This is a specific instance of what OWASP's Agentic Top 10 classifies as ASI03:2026 Identity and Privilege Abuse, which the framework describes as agents that "leverage inherited user or system credentials in problematic ways," retaining "high privilege credentials, session tokens, and delegated access" that get "unintentionally reused, escalated, or passed across agents," and which names "confused deputy scenarios" explicitly among its examples. This entry is narrower than that category: it covers the specific OAuth-proxy and token-audience mechanisms MCP's own specification documents, not every form of credential misuse an agent can commit.
This differs from agent card poisoning in protocol and timing. That entry targets the A2A Agent Card fetched before any session begins, deciding whether a client should trust a counterparty at all. This entry targets the OAuth token flow an already-connected MCP client uses to reach a downstream API, after trust in the MCP server itself has already been established. A deployment running both MCP-connected tools and A2A-discovered agents needs distinct controls for each, since a hardened Agent Card discovery path does nothing to fix a static client ID shared across every MCP client.
Mapping to standards and research
Source | Source-owned term or item | Relationship to this article |
|---|---|---|
Model Context Protocol, Security Best Practices | "Confused Deputy Problem"; "Token Passthrough" | Primary, protocol-owned definitions and MUST-NOT requirements this article's two variants are drawn from directly. |
GitHub Security Advisory GHSA-9gw6-46qc-99vr / CVE-2026-48039 | meta-ads-mcp authentication bypass and credential leak | Direct, CVE-tracked evidence that an ambient-credential fallback combined with an unscrubbed error path leaks a live OAuth-adjacent access token to an unauthenticated caller. |
Asana MCP server incident (2025-06) | Cross-tenant MCP data exposure | Documented real-world incident illustrating the intermediary trust failure the confused deputy pattern describes, independently framed as such by Defakto Security. |
OWASP Top 10 for Agentic Applications 2026 |
| Broader risk category explicitly naming "confused deputy scenarios" among credential-misuse examples; this article covers the narrower, protocol-specific OAuth-proxy and token-passthrough mechanisms. |
MITRE ATLAS |
| Attacker-behavior classification for the credential-exposure consequence documented in CVE-2026-48039, where a standing credential was recoverable through an insufficiently protected error path. |
Agent State Attack | MCP confused deputy and token passthrough | SSA descriptive bundling of the specification's two named terms under one entry, not attributed to the sources above. |
Related terms
- Agent state attack: the umbrella definition, including tool and environment state among the listed target states.
- MCP tool poisoning: the adjacent MCP-protocol surface targeting tool descriptions and results rather than the OAuth handshake underneath a tool call.
- Agent card poisoning: the adjacent surface in a different protocol, targeting pre-session discovery trust rather than an already-connected client's token flow.
- Sandbox configuration escape: another entry targeting tool and environment state, through a writable host configuration path rather than an OAuth credential path.
FAQ
Is this the same thing as an agent's tool description being poisoned?
No. MCP tool poisoning targets content the model reads and can be tricked into treating as an instruction. This entry targets the OAuth authorization plumbing that decides whether a tool call is permitted at all, which the model never sees and which fails independently of whether any tool description was ever compromised.
Does this require the MCP server itself to be malicious?
No, and the documented cases show it does not. The specification describes confused deputy and token passthrough as architectural failure modes a well-intentioned MCP proxy server can fall into through ordinary implementation choices, such as reusing one client ID for simplicity or forwarding a token because building a proper exchange flow is more work. CVE-2026-48039 and the Asana incident both involve legitimate, non-malicious services with an unintended authorization gap.
Does avoiding OAuth-backed MCP servers eliminate this risk?
It removes the specific mechanisms this entry covers, at the cost of losing the delegated, scoped access OAuth is meant to provide. A server falling back to a single static credential for every caller, as in the ambient-credential fallback pattern seen in CVE-2026-48039, can reintroduce an equivalent risk without OAuth being involved at all, since the underlying problem, a shared credential standing in for individual authorization, is not unique to the OAuth flow specifically.
Can this be mitigated without breaking legitimate multi-client MCP proxy deployments?
Yes. Per-client consent registries, audience validation, and token exchange all preserve the ability for one MCP proxy to serve many distinct MCP clients; none require collapsing back to a single shared credential. What they remove is the assumption that a static client ID or a forwarded token can stand in for verifying which specific caller is making which specific request.
Sources
- Model Context Protocol, Security Best Practices (2026-07-28 revision)
- GitHub Security Advisory GHSA-9gw6-46qc-99vr (CVE-2026-48039)
- Defakto Security, What the Asana MCP Bug Reveals About AI Security Gaps (2025-06-19)
- Nudge Security, Asana MCP server data exposure incident
- OWASP Top 10 for Agentic Applications 2026 (Version 2026, December 2025)
- MITRE ATLAS
- MITRE ATLAS data release v2026.06 (2026-06-30)
Verification and change history
Standards and versions referenced: MCP Security Best Practices, 2026-07-28 revision; OWASP Top 10 for Agentic Applications, Version 2026 (December 2025); MITRE ATLAS, data release v2026.06 (2026-06-30); CVE-2026-48039 / GHSA-9gw6-46qc-99vr.
Last verified: 2026-09-25. The MCP specification's Confused Deputy Problem and Token Passthrough sections, the GitHub Security Advisory's technical description and dates, the Defakto Security and Nudge Security accounts of the Asana incident, and the OWASP ASI03 description were read from the sources' own pages on this date. The MITRE ATLAS identifiers were reused from this site's previously verified crosswalk entries.
Change history: 2026-09-25, first version.
Working-term label: Mixed provenance. "Confused Deputy Problem" and "Token Passthrough" are terms defined directly in the Model Context Protocol's own specification. CVE-2026-48039 is a Standard-identified vulnerability. ASI03:2026 is a Standard Term owned by OWASP. AML.T0055 and AML.TA0013 are Standard Terms owned by MITRE. This article's bundling of the two MCP-specification terms under one entry, and its framing of the Asana incident as an illustrative real-world case, are SSA editorial synthesis, not attributed to the sources above.