Why MCP has a security surface at all
The property that makes MCP useful — a model discovers tools from a server at runtime and decides what to call, reading each tool’s natural-language description to understand it — is exactly the property attackers exploit. The model does not reliably distinguish documentation from instructions. A tool description is text the model reads and acts on; if that text contains hidden commands, the model may follow them while showing the user nothing unusual.
This guide is the threat half of a pair. The defense half — the concrete checklist for running MCP safely — lives in MCP security best practices; here we lay out what you’re defending against, because you can’t evaluate a control you don’t understand the attack behind.
Rug pulls: trust that decays
Version pinning matters because MCP trust is not a one-time decision. A rug pull exploits the gap between approval and use: a server presents clean, benign tools when you first connect and review it, then silently changes a tool’s description or behavior later — after it’s earned a place in your config and, often, standing approval to run.
The uncomfortable analogy is a browser extension that ships an innocuous first version, builds an install base, then pushes a malicious update. If your MCP client re-reads tool descriptions on each connection and auto-approves known servers, a changed description is a changed instruction the model may now obey.
The confused-deputy problem
The confused-deputy attack targets a specific but common architecture: an MCP proxy server that sits in front of a third-party API and uses a single, static OAuth client ID for all its users. The MCP specification’s own security best practices document this attack in detail because it’s a real deployment pattern.
The mechanics, compressed: a user legitimately authorizes the proxy, and the third-party authorization server sets a consent cookie for that static client ID. Later, an attacker gets the user to click a crafted authorization link with a malicious redirect URI. Because the consent cookie is already present, the authorization server *skips the consent screen* — and the resulting code is redirected to the attacker, who exchanges it for access as the victim.
The mandated mitigations from the spec are unambiguous: the proxy must implement its own per-client consent (checked before forwarding to the third party), must validate redirect URIs with exact string matching, and must use single-use, properly-bound OAuth state parameters. The same document also forbids token passthrough — a server accepting and forwarding tokens that weren’t issued to it — for closely related reasons.
Exfiltration via tool results
The subtlest vector reverses the direction of trust. It’s natural to worry about what you send *to* a tool; the underrated risk is what a tool sends *back*. Tool results re-enter the model’s context, and if that content contains instructions — a support ticket body, a web page a fetch tool retrieved, a database row an attacker controls — the model may treat them as commands on its next turn.
- Indirect prompt injection — an attacker plants instructions in data your agent will later read via a legitimate tool (a public issue, a review, an email), and the payload fires when the model processes the result.
- Chained exfiltration — injected instructions tell the model to take sensitive context it already holds and pass it to an outbound tool (a URL fetch, a message send), leaking it through a channel that looks like normal tool use.
How the threats map to defenses
Each attack has a corresponding control, and they’re additive — no single one is sufficient:
| Threat | What it exploits | Primary defense |
|---|---|---|
| Tool poisoning | Descriptions read as trusted instructions | Vet servers; make AI-visible text auditable; scan for poisoned descriptions |
| Shadowing | Servers share the model’s attention | Isolate untrusted servers; minimize the connected set |
| Rug pull | Trust granted once, behavior changed later | Pin versions; verify integrity; re-consent on change |
| Confused deputy | Over-trusted proxy with a static client ID | Per-client consent; exact redirect-URI matching; state validation |
| Result-borne injection | Tool output re-entering context as instructions | Treat all results as data; hard trust boundary; scope outbound tools |
| Over-broad tokens | One key that can do everything | Least-privilege scoped keys; approval gates on side effects |
The unifying rule across the whole table: enforce at the tool-execution layer, not in the UI. The client is a model, and a model can be talked around a suggestion the way it cannot be talked around a permission check in code. A policy the model can reason its way past is not a policy.
This is the principle our platform is built on, and we describe how we apply it on the security page: every key runs under a scoped access policy — read-only, no-revenue, no-PII — enforced where tools execute, with gated fields redacted from outputs. It doesn’t make the threats above disappear; it caps their blast radius, which is the realistic goal. The full defensive checklist is in MCP security best practices.
Frequently asked questions
What is MCP tool poisoning?
Tool poisoning is an attack where a malicious or compromised MCP server embeds adversarial instructions inside a tool’s natural-language description — the text the model reads to understand the tool. Because models treat that text as trustworthy, the model may follow the hidden instructions (e.g. exfiltrating data) while the visible tool output looks completely normal.
What is an MCP rug pull?
A rug pull exploits trust over time: an MCP server presents clean, benign tools when you first review and approve it, then silently changes a tool’s description or behavior later. If your client re-reads descriptions and auto-approves the known server, the changed text becomes a new instruction the model may obey. Defend by pinning versions and re-consenting on change.
Can data leak through MCP tool results?
Yes. Tool results re-enter the model’s context, so content a tool returns — a web page, a ticket, a database row an attacker controls — can carry instructions that hijack the model’s next turn (indirect prompt injection), potentially chaining into exfiltration through an outbound tool. Treat all tool output as untrusted data, never as instructions.
What is the confused-deputy problem in MCP?
It’s an OAuth attack on MCP proxy servers that use a single static client ID for a third-party API. A leftover consent cookie lets an attacker’s crafted authorization request skip the consent screen and redirect the auth code to them. The MCP security spec mandates per-client consent, exact redirect-URI matching, and proper state validation to prevent it.
How do I protect against malicious MCP servers?
Layer defenses: connect only vetted servers, keep the connected set minimal, pin versions and verify integrity, disable auto-approval for tools touching credentials/files/network, use least-privilege scoped keys with approval gates on side effects, treat all tool results as untrusted data, and enforce every policy at the tool-execution layer rather than in the UI.
Sources
BusinessMCP Team
Every guide is written from running BusinessMCP on its own platform — the match rates, reply rates, and deliverability lessons are from our own data, not recycled blog folklore. About BusinessMCP
Turn your business into one AI-ready MCP server
Connect your tools, install one tracking script, and expose your unified data to any AI agent through a single secure endpoint.
Get started free