How do you prevent prompt injection in MCP servers and AI agents?

There's no deterministic patch for prompt injection the way parameterized queries mostly killed SQL injection. So the goal is containment rather than a cure. The full set of controls sits below, and every item gets unpacked in the sections that follow.

  • Least-privilege scoped tokens. Give the agent the narrowest credential that still lets it do its job. A hijacked agent can only reach what its token can reach.
  • Per-session and per-repo isolation. One session shouldn't span your public issue tracker and your private repos at once. Shrink what a single run can touch.
  • Allowlist-based URL and SSRF controls. Block private and reserved IP ranges, force HTTPS, and don't hand-roll IP parsing.
  • Human approval on high-impact tool calls. Keep a person able to deny a tool invocation before it fires.
  • Trust separation. Treat tool descriptions and runtime tool results as different trust domains, because they are.
  • Constrained capability. Use Dual LLM or CaMeL so an injected instruction has almost nothing it can actually do.

One caveat up front: this is an engineering threat model, not exhaustive security advice. It's the mechanism-level view I'd want a teammate to have before they ship an MCP server.

Direct vs indirect prompt injection, explained

Prompt injection in agent systems comes in two flavors, and the dangerous one is the quiet one.

Direct injection is the obvious case. A human types adversarial instructions straight into the prompt. On a shared or multi-user agent that's a genuine problem, but at least the attacker is a user you can see.

Indirect injection is where the adversarial instructions ride in through content the agent ingests as data: tool outputs, retrieved documents, emails, GitHub issues, web pages. The model can't reliably tell trusted instructions from untrusted data because it all lands in the same context window. There's no <untrusted> tag the model respects by default. Simon Willison flagged MCP's exposure to exactly this on 9 April 2025, and researchers have since shown the same injection can be turned to both attack and defense, which tells you how blurry the direct versus indirect line gets in practice. Indirect wins as the dominant MCP threat for one structural reason: MCP tool results flow straight into the model context. You connect a server, the model calls a tool, and whatever comes back is now part of the conversation the model reasons over. If an attacker controls that returned data, they get to shape what the model does next.

The lethal trifecta: why injection becomes theft

Injection on its own is mostly a nuisance. It turns into a data breach only once it's paired with the right ingredients. Willison's lethal trifecta, the term he coined on 16 June 2025, names the three conditions that turn a clever prompt into real damage:

1. Access to private data the agent can read. 2. Exposure to untrusted content that can smuggle instructions. 3. An exfiltration vector, some way to send data back out.

An agent holding all three is exploitable. The useful part: knock out any one leg and the data-theft outcome collapses. Can't reach private data? Nothing to steal. No untrusted content in context? No smuggled instructions. No egress? The attacker's instructions have nowhere to ship the loot. Most of the practical defenses in this post are just disciplined ways of removing one leg of that tripod. Design so your agent rarely holds all three at once and you've already beaten any classifier.

Tool poisoning and rug pulls: the MCP-specific trust gap

MCP adds two injection variants you don't get from a plain chatbot, and both exploit the same blind spot.

Tool poisoning hides malicious instructions inside an MCP tool's description or metadata. The model reads that description; the user usually doesn't. So the model gets steered at connect and registration time, before anyone runs anything. Invariant Labs disclosed this class on 6 April 2025, and it's now listed as MCP03 in the OWASP MCP Top 10, though the OWASP MCP Top 10 is still a beta project as of 2026, not a finalized catalog like the released flagship Agentic list. The root gap: a tool description might get reviewed once at connect time, but the tool responses at runtime pour into the model context with no equivalent check. Reviewing the description once does nothing to catch what those runtime responses smuggle in later. And the surface keeps widening; Palo Alto's Unit 42 has since mapped fresh injection vectors through MCP sampling. There's a fuller breakdown of the description trick in MCP tool poisoning.

Rug pulls are worse in a lazy way. An MCP tool can mutate its own definition after you approve it. Safe on day one, malicious on day seven, because clients re-fetch tool definitions and don't re-verify them. Willison described this class in the same 9 April 2025 post. Approval isn't a one-time event when the thing you approved can rewrite itself overnight.

Real incidents: EchoLeak and the GitHub MCP toxic agent flow

Two disclosures made this concrete. Both are proof-of-concept, responsibly disclosed, with no evidence of exploitation in the wild. That distinction matters, so it's worth stating plainly.

EchoLeak (CVE-2025-32711, CVSS 9.3) was a zero-click indirect prompt-injection chain in Microsoft 365 Copilot, found by Aim Labs. Cato Networks hosts the origin writeup after acquiring Aim. Aim Labs named the root-cause technique an LLM Scope Violation, where untrusted email content pulls privileged internal data outside the scope it was ever meant to touch. A single crafted email, no click required, steered Copilot into reading internal RAG context and exfiltrating it. The chain walked past several best-practice guardrails at once: Microsoft's XPIA cross-prompt-injection classifier, external-link redaction, Content-Security-Policy, and reference-style markdown. Per the same Cato writeup, Aim built the PoC in January 2025, disclosed privately, and published in June 2025, while Microsoft patched server-side by May 2025 and reported no in-the-wild exploitation.

The GitHub MCP toxic agent flow came from Invariant Labs on 26 May 2025. A malicious prompt planted in a public GitHub issue hijacked an agent running the official github-mcp-server (14,000-plus stars at the time) into reading the user's private repositories and leaking their contents into an attacker-visible pull request. Invariant was blunt that this isn't a bug in the server code. It's an architectural problem with no tidy fix. Their mitigations: one repository per session, least-privilege tokens, and runtime guardrails and scanners. Notice it's the lethal trifecta again: private data, untrusted issue content, and a PR as the exfiltration vector.

What the standards say: OWASP Agentic Top 10 and the MCP spec

The field finally has flagship references written for agents, not just models.

On 9 December 2025 the OWASP GenAI Security Project shipped the OWASP Top 10 for Agentic Applications, its first flagship list built specifically for autonomous agents. ASI01 Agent Goal Hijack sits at number one, and it folds prompt injection into a broader class: an attacker alters the agent's objectives or decision path through malicious content hidden in documents, emails, and RAG results, exploiting the agent's own planning and reasoning. OWASP's recommended mitigations are rigid operational constraints and guardrails, continuous behavioral anomaly monitoring, and treating the agent's core logic as privileged code. The full list runs ASI01 Agent Goal Hijack, ASI02 Tool Misuse, ASI03 Identity and Privilege Abuse, ASI04 Agentic Supply Chain, ASI05 Unexpected Code Execution, ASI06 Memory and Context Poisoning, ASI07 Insecure Inter-Agent Communication, ASI08 Cascading Failures, ASI09 Human-Agent Trust Exploitation, and ASI10 Rogue Agents.

The official MCP specification also ships a dedicated Security Best Practices document in the 2025-06-18 spec line, with normative MUST and SHOULD countermeasures. Pin to a spec version when you quote it, since the wording is versioned. The concrete rules come next.

MCP prompt injection best practices: how to prevent the outcomes

Here's the how-to, grounded in the MCP spec's normative rules. These are the controls worth checking in a server review.

  • Token passthrough. The spec is explicit: MCP servers MUST NOT accept tokens that weren't explicitly issued for the MCP server. Passthrough breaks audit trails, bypasses rate-limiting and validation, and turns your server into an exfiltration proxy the moment a token leaks.
  • The confused deputy. An MCP proxy using a static client ID with a third-party auth server, plus dynamic client registration and consent cookies, can let an attacker skip the consent screen and steal an authorization code. Proxies MUST get per-client consent before forwarding to the third-party flow, do exact redirect_uri matching, and use single-use cryptographic OAuth state.
  • SSRF. Tools that fetch model- or server-supplied URLs can be aimed at internal services and cloud metadata endpoints like http://169.254.169.254/. Force HTTPS, block private and reserved IP ranges, validate redirect targets, use egress proxies, and don't hand-roll IP validation, because encoding tricks eat custom parsers for breakfast.
  • Session hardening. Servers MUST NOT use sessions for authentication, MUST verify every inbound request, MUST use secure non-deterministic session IDs, and SHOULD bind session IDs to user info (a <user_id>:<session_id> format) so a guessed ID can't impersonate someone else.
  • Detection as one layer. Microsoft's Spotlighting work from 28 April 2025 transforms untrusted input with delimiting, datamarking, and encoding so the model can tell system instructions from external data, paired with Prompt Shields and supply-chain verification. Useful, but EchoLeak walked past a whole stack of detectors, so treat classifiers as one layer among many.
  • Capability constraints. The design-patterns paper from 13 June 2025 lays out six patterns. The Dual LLM pattern keeps a privileged LLM away from untrusted content entirely; it only manipulates symbolic variables produced by a quarantined LLM. CaMeL, from Google DeepMind, generates the privileged control flow in a sandboxed DSL. Both constrain the action space instead of trying to detect every injection. That's the shift that actually moves the needle. For the server-hardening companion to this, see MCP server security.

Govern the data plane, not just the model

Most of the defenses above govern what the agent will do. The leg that keeps getting ignored is what the agent can reach. If a hijacked agent reaches raw PII, your last line of defense was a classifier, and EchoLeak is a museum of classifiers that lost.

This is the data-plane angle, and it's where DataShield sits. Tokenize sensitive fields at ingest, and a hijacked agent that exfiltrates a record finds tokens, not raw customer data. The trifecta's first leg, access to private data, gets weaker by construction. Authorize per tool call instead of per session, with mid-session revocation, so a token that looked fine at minute one can be pulled the instant behavior drifts. That's the per-call model at /auth and the field-level view at /ontology. Then seal every tool call into a tamper-evident audit chain you can actually verify at /verify, because OWASP's advice to treat agent logic as privileged code only means something if you can prove after the fact what the agent touched. Governing the reachable data is the one control that still holds when the model gets talked into something dumb. The full architecture is written up at /architecture.

Watch: MCP prompt injection, explained

Three short explainers on how agents get hijacked through injection, and what to do about it.

MCP prompt injection explainer video

MCP prompt injection, how AI gets hacked (TestMu AI)

How AI agents get hijacked by prompt injection video

How an agent gets hijacked (Devsplainers)

Microsoft warning on MCP agent poisoning video

Poisoning agents via MCP (IT SPARC Cast)

The honest caveat: prompt injection isn't solved

I'd be selling you something if I ended on a tidy bow. Anthropic said it plainly on 24 November 2025: prompt injection is not solved and stays an active research area. Their posture is defense-in-depth: reinforcement-learning training for injection robustness, classifiers scanning all untrusted content entering the context (including hidden text and manipulated images or deceptive UI), continuous human red-teaming, and external benchmarking. They cite roughly a 1% attack success rate for their browser agent after mitigations, but treat that as a vendor-reported, context-specific number from a browser-use benchmark, not a general MCP figure.

So the MCP spec requires explicit user consent before a tool is invoked, keeping a human in the loop able to deny tool invocations, OWASP wants continuous anomaly monitoring, and everyone serious layers controls because no single one holds. Build like the injection will land. Then make sure that when it does, the agent is holding tokens instead of secrets, its token can be revoked mid-call, and every action is on a chain you can verify. That's not a cure, but it's what stops a contained incident from becoming a breach you have to disclose to regulators. For the containment model applied end to end, /security and /verify are the fastest tour.

Frequently asked questions

What is the difference between direct and indirect prompt injection?

Direct injection is when a human types adversarial instructions straight into the prompt. Indirect injection is when those instructions arrive inside content the agent ingests as data, such as tool outputs, retrieved documents, emails, GitHub issues, or web pages. Indirect is the dominant MCP threat because MCP tool results flow straight into the model's context window, where the model can't reliably separate trusted instructions from untrusted data.

Can prompt injection in MCP be completely prevented?

No. There is no deterministic fix, and Anthropic stated on 24 November 2025 that prompt injection remains unsolved and an active research area. The realistic goal is containment: least-privilege scoped tokens, per-session isolation, allowlist-based SSRF controls, human approval on high-impact calls, and constrained-capability designs like Dual LLM or CaMeL that limit what a successful injection can actually do.

What is the lethal trifecta in AI agent security?

Coined by Simon Willison on 16 June 2025, the lethal trifecta is the combination that turns prompt injection into real damage: access to private data, exposure to untrusted content, and an exfiltration vector to send data out. An agent with all three is exploitable. Remove any one leg and the data-theft outcome collapses, which is why most practical defenses aim to break at least one leg of that tripod.

What is MCP tool poisoning?

Tool poisoning hides malicious instructions inside an MCP tool's description or metadata, which the model reads but the user usually doesn't, so the model gets steered at connect and registration time. Invariant Labs disclosed it on 6 April 2025, and it now sits in the OWASP MCP Top 10 as MCP03, though that project is still in beta as of 2026 rather than a finalized catalog. The root gap is that tool descriptions may be reviewed once at connect time, while runtime tool responses enter the model context with no equivalent check.

Is EchoLeak a real-world attack?

No. EchoLeak (CVE-2025-32711, CVSS 9.3) was a proof-of-concept zero-click indirect prompt injection in Microsoft 365 Copilot, found by Aim Labs and responsibly disclosed. Aim named the root-cause technique an LLM Scope Violation. A single crafted email caused Copilot to read internal RAG context and exfiltrate it, bypassing the XPIA classifier, link redaction, CSP, and markdown handling. Microsoft patched server-side by May 2025 and reported no evidence of in-the-wild exploitation.