What is the 'confused deputy' problem, and how can a malicious MCP server exploit it?

5 minadvancedmcpsecurityconfused-deputyauthorization

Quick Answer

A confused deputy is a program that's tricked into misusing its own legitimate authority on an attacker's behalf. In MCP's context, this typically shows up when an MCP server itself holds a privileged credential (say, an OAuth token for some upstream API, or elevated database access) and blindly acts on whatever a client/model asks, without verifying the request actually comes with the user's own authorization for that specific action. For example, if a server holds one shared, highly-privileged upstream token for all its users rather than a per-user scoped token, a malicious or compromised client could ask that server to perform an action on behalf of a different user's data, and the server — trusting its own privileged credential rather than checking who's actually asking — would carry it out. The mitigation is to ensure the server always authorizes the specific requesting user for the specific action, rather than treating "I possess a powerful credential" as sufficient permission to act.

Detailed Answer

The confused deputy problem is a classic security pattern, decades older than MCP. MCP's server-as-intermediary shape reproduces it almost exactly.

The classic shape of the problem

A "deputy" — here, the MCP server — holds real authority, like an upstream API credential, that it exercises on behalf of callers. Say the deputy can't tell "an authorized caller asking for something they're entitled to" apart from "any caller asking for anything." Then an attacker doesn't need the deputy's own credential. They just need to convince the deputy to use its authority for them.

A concrete MCP scenario

MCP Server (holds one shared, admin-level OAuth token to an upstream CRM API)
     |
     v
tools/call: get_customer_record(customer_id="12345")
     |
     v
Server, trusting only its own admin token, fetches customer 12345's
record and returns it — without checking whether the CALLING USER
(as opposed to the server itself) is actually authorized to see that
specific customer's data.

Say the server's authorization logic stops at "do I, the server, have a valid credential for the upstream API." It never asks "is this specific user entitled to this specific record." Then any client connected to the server can read any customer's data. The server has become a confused deputy, using its own broad privilege on behalf of a request that should have been scoped much narrower.

The mitigation

  • Don't hold one shared, maximally-privileged credential for all users. Where possible, obtain per-user, appropriately-scoped tokens, via the OAuth flow the user themselves completed, rather than a single service-level credential used indiscriminately.
  • Re-check authorization at the point of the action, using the identity of the actual calling user or session, not just the fact that the server itself possesses some valid upstream credential.
  • Scope tokens narrowly (least privilege — covered later in this topic), so even if a confused-deputy scenario occurs, the blast radius of what can be accessed is limited.

Why this is worth calling out specifically for MCP

MCP servers are often built as thin wrappers around an existing API. It's tempting to just embed one API key or token for the whole server and call it done. That pattern is exactly what creates a confused deputy. The server is trusted more than any individual request actually warrants, and every caller inherits that trust regardless of who they really are.

Related Resources