The scariest MCP attacks are not the ones where a malicious tool does something obviously bad. They are the ones where a legitimate tool, one you approved and use every day, gets talked into doing something bad on your behalf. That pattern has a name in computer security going back decades: the confused deputy problem. It applies to MCP almost exactly as written, and it is worth understanding separately from prompt injection, because the fix is different.
What a confused deputy actually is
A “deputy” in this sense is any program that holds more authority than the party it is currently acting for — it has its own credentials, separate from yours, that it uses on your behalf. The classic example: a compiler that has permission to write to a shared billing log, so it can record its own usage. If an attacker can pass that compiler a filename that happens to point at the billing log instead of a normal output file, the compiler faithfully overwrites the log — using its own write permission, not the attacker’s, because the compiler never had a way to tell “write where I was told” apart from “write where an attacker wanted.” Nothing was hacked. The deputy just did exactly what it was authorized to do, pointed at the wrong target.
How this maps onto an MCP-connected AI agent
An AI client connected to MCP servers is a deputy in exactly this sense. Once you complete OAuth for, say, an email or ticketing server, the agent is holding a real credential — your credential, delegated to it — and it can call every tool that credential authorizes for as long as the session or token lasts. That is normal and useful. The risk shows up when the agent also reads content it did not generate and was not vetted by you: a web page, an email body, a support ticket, a file attachment, the output of another tool. If that content contains instructions, and the model follows them, the agent can end up using its own, legitimately granted tool access to do something you never asked for — forward a message, create a record, move money, delete a file — because from the tool’s point of view, a properly authorized client made a properly formed call. This is the same mechanism behind prompt injection and tool poisoning, which we covered in MCP prompt injection and tool poisoning, but the confused deputy framing puts the emphasis in a more useful place: the problem is not just that untrusted text can influence a model. It is that the model’s own valid authority is the thing being misused, which is why scanning a server’s tool descriptions for hidden instructions — useful as that is — only catches part of it.
Where it shows up in practice
A few shapes this tends to take with real MCP tool chains:
- Read-then-write chains. A server that can both fetch external content and take an authorized action (send an email, post a message, create an issue) is the highest-risk combination, because the same session that reads untrusted text can also act on it.
- Cross-server chains. One server’s output feeds into a second server’s tool call. The second server has no way to know its input passed through untrusted content upstream — it just sees a call from an authorized client.
- Broad OAuth grants. As we wrote in MCP OAuth scopes explained, most MCP servers today grant a token that covers the entire tool list rather than a narrow scope. The wider the grant, the more damage a confused call can do.
Why this is hard to fully scan away
A pre-connection security check — the kind gate’s MCP security scanner runs — is genuinely useful: it catches hidden instructions planted directly in a tool’s description or schema, which is a common and cheap attack. But a confused deputy attack does not require the server itself to be malicious at all. The server can be exactly what it claims to be; the untrusted content can arrive later, from a completely different source, well after the server passed its check. That is a property of how the agent is allowed to act, not a property you can catch once and be done with.
What actually reduces the risk
Nothing here is a single fix. A few things compound:
- Least privilege on the grant itself. Request and accept the narrowest scope a server offers, and revisit it — see OAuth scopes explained.
- Per-tool rules, not per-server ones. A tool that both reads external content and takes an action is a reasonable candidate for “ask” instead of “allow,” even on a server you otherwise trust. We cover this model in MCP access control for teams.
- Human approval on the calls that matter. For the small set of tools that can cause real damage — sending, deleting, paying — a confirmation step in front of the call is the most direct defense, discussed in human-in-the-loop approvals for AI tool calls.
- A log that shows the chain, not just the call. When something does go wrong, you want to see what content the agent read right before the action it took, not just the action in isolation — see MCP observability and audit logs.
The bottom line
A confused deputy attack does not need a bad server, a broken OAuth flow, or a cleverly worded tool description — it just needs an agent with real access and one piece of content you did not vet. Treat any tool that both reads untrusted input and can take a consequential action as the highest-risk combination in your setup, put a narrower rule or a human checkpoint in front of it, and keep a log that lets you reconstruct what the agent read right before it acted. That is the part a one-time server scan was never going to cover.