What are the security risks of MCP servers, and how do you secure them?

Every MCP risk falls into a handful of buckets, and each one has a control that genuinely does something.

  • Prompt injection (direct and indirect). Attacker text in a tool result, a document, or a web page overrides what you told the agent. OWASP's Top 10 for Agentic Applications, released in December 2025, makes agent goal hijack its number one category, ASI01, and folds prompt injection into it, so this class is the root cause hiding under most of the others.
  • Tool poisoning. A tool buries instructions in its own description or metadata. The model reads them; you never do.
  • Rug pull. A tool behaves during review, then changes after you approve it.
  • Confused deputy and excessive agency. One over-credentialed agent gets talked into using its access beyond intent.
  • Credential theft, over-scoped tokens, and SSRF. Old problems, now with an autonomous operator pulling the levers.

Ranked by leverage, the controls are a human in the loop for destructive actions, tool integrity verification (signatures plus version pinning), sandboxing for local servers, HTTPS and private-range blocking for remote servers, and least privilege on every token. Below I pair each attack with the defense that stops it, along with the real incidents that make the case. One caveat: this is an engineering threat model, not a full security program.

What is MCP, and why does it widen the attack surface?

MCP (Model Context Protocol) is an open standard Anthropic introduced in November 2024. It gives models and agents one uniform way to reach external tools, data, and services through MCP servers, in effect USB for AI tools. It saw wide uptake through 2025 and into 2026.

The shift it creates is easy to underrate. Before MCP, a language model mostly produced text and a human decided what to do with it. With MCP, the model calls tools that send email, move money, query databases, and run commands, often in a loop with nobody reading each step. The model no longer just talks; it acts.

Every server you connect adds new code, new network egress, and new text flowing into the model's context. That last one matters most, because inside an agent, data and instructions ride the same channel, and the model cannot tell them apart.

Prompt injection, the primitive under almost every MCP attack

A model cannot reliably separate the instructions you gave it from instructions that appear inside the data it reads. Direct injection is a user typing "ignore your rules." Indirect injection is the dangerous variant, where the malicious text lives in a document, a web page, a Jira ticket, or a tool's output, and the agent swallows it while doing perfectly ordinary work.

Your support agent reads a customer email to draft a reply. Somewhere in that email sits a line addressed to the assistant, telling it to export the last 50 tickets to an outside address. If the agent has an export tool and no gate, it might comply. Nothing was hacked in the traditional sense. The agent followed instructions faithfully. They simply were not yours.

This is why OWASP's Top 10 for Agentic Applications, published in December 2025, ranks agent goal hijack as ASI01, its number one category, and folds prompt injection directly into it rather than listing it separately. Most of the attacks that follow are really just different ways to deliver this one primitive. For the direct-versus-indirect breakdown and the defenses that contain it, see MCP prompt injection.

Tool poisoning and rug pulls, when the tool itself is the attacker

Sometimes the tool is not a victim of injection but the source of it.

With tool poisoning, the malicious instructions sit inside a tool's description or metadata, the part the model reads to understand how to use it and the part a human almost never inspects. Invariant Labs showed how this works in a controlled demonstration. A poisoned tool description on a secondary server instructed the model to exfiltrate a user's entire WhatsApp message history through a call that looked completely benign. The user saw a normal tool while the model saw hidden orders. Underneath, it is indirect prompt injection dressed up as a legitimate tool.

A rug pull is the time-delayed version of the same trick. A tool behaves during review, you approve it, and its description or behavior changes afterward. What you signed off on is not necessarily what runs next week.

At least one case has already shown up outside the lab. Security researchers at Koi Security reported postmark-mcp in late September 2025, an MCP server that silently added a BCC to every email an agent sent, quietly copying communications to an attacker-controlled address. It reached roughly 1,600 downloads before it was pulled. It was among the first confirmed malicious MCP servers seen in the wild. No exploit, no CVE, just a helpful-looking server doing one extra thing nobody agreed to. For the full mechanism, the real incidents, and the defenses, see MCP tool poisoning.

Confused deputy, excessive agency, and stolen tokens

A confused deputy problem appears when you hand one agent every key. That agent holds credentials for email, the CRM, the cloud, and payments, so an attacker who can influence its instructions, typically through the prompt injection described above, borrows all of that authority at once. The agent has real power and poor judgment about who is actually asking.

Excessive agency is the same weakness viewed from the design side. When an agent can do far more than its task requires, a small compromise becomes a large one.

Add credential and token theft and over-scoped permissions on top, and a single hijacked session can reach systems the task never needed to touch. The remedy is unglamorous and effective. Never give one agent all the credentials, scope tokens to a specific tool and a specific action, and authorize each call rather than each session. Our take on that model lives at /auth.

What does the MCP auth spec itself warn about?

The MCP security best practices spec calls out two attacks by name. The first is a confused-deputy problem in OAuth proxying. An MCP server that proxies OAuth with a static client ID plus a stored third-party consent cookie can let an attacker skip the consent screen through dynamic client registration and steal an authorization code. The spec's fix is per-client consent, and it makes that a MUST.

The second is token passthrough, which the authorization spec forbids outright. An MCP server MUST NOT accept tokens that were not explicitly issued for that server. Pass a client's token straight through to a downstream API and you break the audit trail and turn the server into an exfiltration proxy. MCP servers act as OAuth 2.1 resource servers, so they must validate token audience before trusting anything. Both failures are authorization failures, which is why we treat /auth as load-bearing rather than decorative.

SSRF and the network edge

Server-side request forgery, or SSRF, is the network-layer way in. A remote MCP server, or a tool it exposes, gets coaxed into making requests to private IP ranges such as cloud metadata endpoints, internal admin panels, and databases that assume the network itself is the perimeter. If your agent can fetch a URL, someone will eventually feed it http://169.254.169.254/ to see what comes back.

Remote servers need two defenses here, and neither is optional. Enforce HTTPS so traffic cannot be trivially intercepted or tampered with, and block outbound requests to private and link-local ranges by default, allowlisting only the destinations you genuinely need.

The defenses that actually work (spec-level controls)

The MCP spec and common practice offer five controls. Lined up against the attacks above, they map cleanly.

1. Human in the loop. The MCP spec recommends this rather than mandating it: it says there SHOULD always be a human in the loop with the ability to deny tool invocations. That is a SHOULD, not a MUST, so the enforcement is on you. Annotate tools with risk classes and require explicit approval for anything destructive or irreversible. This is your backstop against injection-driven actions, since even a perfectly hijacked agent has to get past a person before it wires money.

2. Verify tool integrity. Version pinning and consent gates come from the spec itself. Cryptographic signature verification does not; it is an emerging best practice rather than a spec mandate. Pair the two and you keep a tool from silently changing under you, which directly counters rug pulls and makes tool poisoning much harder to slip in unnoticed.

3. Sandbox local servers. Apply filesystem restrictions, require explicit consent for OS commands, and show the full command before it runs. If a server wants to delete something, you should see the whole line first.

4. Harden remote servers. HTTPS everywhere, block private IP ranges, and cut off SSRF at the egress.

5. Least privilege. Scope tokens narrowly, authorize per tool call, and never hand one agent every credential. This is what keeps a confused-deputy slip from becoming a full breach.

The usual failure mode is skipping them because the demo worked.

The half everyone skips, govern the data plane

There is a part most MCP-security writing quietly drops. Everything above governs the transport and the tool layer, meaning what the agent is allowed to invoke and how the bytes move. It says almost nothing about what the agent can actually reach once a call goes through.

That is the other half of the threat model. Suppose your five controls all hold, but a cleverly injected agent still gets one legitimate query out. What comes back? If your systems return raw customer identifiers, the agent, or whoever is steering it, now has PII. If sensitive fields are tokenized at ingest, the agent finds tokens instead of raw identifiers, and an exfiltration yields a meaningless token set rather than names, cards, and record numbers. Same breach, far smaller blast radius.

Simon Willison named this pattern in June 2025 as the lethal trifecta: access to private data, exposure to untrusted content, and a way to exfiltrate externally. An agent is exploitable when it has all three, and removing any one leg collapses the attack. Tokenizing the data plane removes the private-data leg. The agent reaches tokens, not raw PII, so even if untrusted content hijacks it and an exfiltration path exists, there is nothing sensitive to carry out.

The principle is worth keeping front of mind. Govern what agents can reach, not only what they will do. In our stack at DataShield, every governed tool call passes a scope ceiling and a mid-session revocation re-check before dispatch, so a token yanked mid-conversation stops working immediately instead of at the next login. Every call is also sealed into a tamper-evident audit chain you can verify yourself at /verify. For the mechanics, the architecture page goes deeper, and /ontology covers how fields get classified for tokenization in the first place.

Watch: MCP security and tool poisoning

Three short watches that pair with the threat model above, from a plain risk overview to a live tool-poisoning walkthrough.

MCP security risks explained overview video

MCP security risks explained (Tenable)

MCP tool poisoning vulnerability walkthrough video

MCP tool poisoning, a live walkthrough (sublimetechie)

Microsoft warning on MCP agent poisoning video

Microsoft on MCP agent poisoning (IT SPARC Cast)

MCP security best practices: a practical hardening checklist

Use this as a pre-ship gate.

  • Inventory every server and tool. You can't govern what you never listed. Know the source, the maintainer, and the version of each. Install-time supply-chain attacks, typosquatted package names and post-publish version swaps on npm and PyPI, are a named class, tracked by OWASP as ASI04 Agentic Supply Chain Vulnerabilities, and postmark-mcp was exactly that: a malicious package impersonating the real one.
  • Pin versions and verify signatures. No auto-updating tools in production. A changed description is a change-control event, not a background sync. Pinning is also your defense against a post-publish version swap slipping a poisoned build in under a name you already trust.
  • Require human approval for destructive or irreversible actions. Tag tools by risk class and gate the dangerous ones.
  • Scope every token to one tool and one action. Authorize per call. Assume any single credential can be borrowed by an injected instruction.
  • Sandbox local servers. Restrict the filesystem, require consent for OS commands, print the full command before execution.
  • Harden remote servers. HTTPS only. Block private and link-local IP ranges. Allowlist egress.
  • Treat all tool output as untrusted input. It can carry injection. Don't let a tool result silently rewrite the agent's goal.
  • Tokenize sensitive fields before the agent can read them. So a worst-case exfiltration returns tokens, not identities.
  • Log every tool call to a tamper-evident chain. When something goes sideways, you want a record you can actually trust. See /security for how we wire this end to end. In the EU, this is also how you meet EU AI Act Article 12 logging.

That last third of the list, the data-plane items, is where most deployments are thin. Close that gap and a hijacked agent that slips past every other control still finds very little worth taking. If you want to see it running, request a quote.

Frequently asked questions

What is the most common MCP server attack?

Prompt injection, both direct and indirect. OWASP's Top 10 for Agentic Applications, released in December 2025, makes it the number one category, ASI01 agent goal hijack, and folds prompt injection into it rather than listing it separately. Most other MCP attacks, including tool poisoning and rug pulls, are really just ways to deliver the same underlying problem, which is attacker-controlled text overriding the agent's instructions.

Has a malicious MCP server actually been found in the wild?

Yes. postmark-mcp, reported by Koi Security, was among the first confirmed cases in the wild. It silently added a BCC to every email an agent sent, copying messages to an attacker-controlled address. Separately, and as a controlled demonstration rather than a real-world incident, Invariant Labs showed a poisoned tool description that made a model exfiltrate a user's entire WhatsApp history through a benign-looking call.

What is tool poisoning in MCP?

A malicious or compromised tool hides instructions inside its description or metadata. The model reads that text and acts on it, while a human reviewing the tool usually never sees it. Structurally it is indirect prompt injection. Version pinning and signature verification are the main defenses.

How do I stop an MCP agent from leaking sensitive data?

Use two layers. Constrain what the agent can invoke (least privilege, per-call authorization, human approval for risky actions), and constrain what it can reach (tokenize sensitive fields at ingest so a compromised agent retrieves tokens, not raw PII). The second layer is the one most guides skip.

Is a human-in-the-loop requirement enough to secure MCP?

No, but it is your strongest single backstop. The MCP spec recommends it rather than requiring it: the text says there SHOULD always be a human in the loop with the ability to deny tool invocations. That is a SHOULD, not a MUST, so treat it as a strong default you still have to enforce, and require approval for destructive actions. Pair it with tool integrity verification, sandboxing, SSRF protection, least privilege, and data-plane governance. No single control covers the whole threat model.