MCP security
Tool poisoning, rug pull, shadowing, line jumping. Cited to the researchers who named them.
A tool description is a prompt. It is written by whoever runs the server, delivered straight into the context window, and shown to the user in a shortened form that leaves the interesting part out.
The whole module in one sentence
Invariant Labs found this in April 2025. Read it slowly, because every attack below is a variation on it.
The attack exploits the fact that AI models see the complete tool descriptions, including hidden instructions, while users typically only see simplified versions in their UI.
Two audiences, two versions, one object. Everything else is what an attacker does with the gap.
Look at both versions
Four named attacks, each shown as the user's view and the model's view of the same tool. The first payload is the published proof of concept, reproduced as written.
Two views of one tool
MCPA malicious server hides instructions inside a tool description. The model reads them; the user never sees them.
Invariant Labs, 1 April 2025
add Adds two numbers. a: number b: number
What the gap buysThe user approves an addition. The model reads the SSH private key and passes it as a third argument. Invariant note that Cursor's confirmation dialog does not show the full tool input even in its extended mode, so the key stays hidden at the moment of approval.
Reaches the modelWhen the tool list is loaded, before any tool is called.
Notice what none of these needed. No compromised model, no jailbreak, no clever phrasing aimed at the model's safety training. The attacker wrote documentation.
What the standard does say
OWASP treats connected tools as a supply chain rather than as a prompt problem, and its mitigation is unusually specific.
Pin, sign, and verify every MCP server and third-party tool package, audit tool descriptions for hidden instructions, and monitor tool composition.
Then, in the next sentence, it says what pinning does not do. This is worth quoting in full to anyone who thinks version pinning closes the issue.
Pinning does not stop a payload shipped in the pinned version or tool-description poisoning that leaves the version unchanged.
Map that onto the four attacks. Pinning defeats the rug pull, because a rug pull needs the description to change after approval. It does nothing about a server that was hostile at version 1.0.0.
| Attack | Does pinning help? | What actually bounds it |
|---|---|---|
| Rug pull | Yes. This is the case pinning is for. | Pin and verify. Re-approve on change rather than on install. |
| Tool poisoning | No. The payload ships in the pinned version. | Read the full description before connecting, and scope what the server's tools can reach. |
| Tool shadowing | No. The malicious server is pinned and honest about its own version. | Isolate servers from each other. A server should not be able to describe another server's tools. |
| Line jumping | No. Nothing is invoked, so nothing is versioned at the moment of attack. | Treat connection as the trust decision, because the approval dialog happens after the payload arrives. |
An MCP server is a dependency with credentials
Module 3.3 has the incident: the postmark-mcp package BCC'd outbound email to its author across an estimated 300 organisations. No injection was involved anywhere. The package was hostile from installation.
That is the frame worth carrying. An MCP server runs with the agent's credentials and can describe its own capabilities to the model, so it deserves the review any dependency with those rights would get, plus one more question that ordinary dependencies do not raise.
Deep diveToxic agent flows, and why the GitHub case is the template›
Invariant's GitHub MCP finding is worth reading alongside module 3.1. An attacker files an issue on a public repository, the owner asks their agent to look at open issues, and the agent leaks from a private one.
They call the pattern a toxic agent flow: an agent manipulated into performing unintended actions, such as leaking data or executing malicious code. The useful part of the framing is that it is a property of the flow rather than of any single component. The MCP server is correct, the agent is correct, the permissions are as configured, and the composition leaks.
Which is why testing one server at a time will not find it. The finding lives in the combination.
Reduces attack rate· expected to degrade
Bounds blast radius· survives adaptive attack
~/.ssh/id_rsa fails when the tool has no filesystem access to grant.Sources
- T2Invariant Labs (Beurer-Kellner, L., & Fischer, M.), 1 April 2025 · MCP Security Notification: Tool Poisoning Attacks. Origin of tool poisoning, rug pull and tool shadowing, and of the add()/sidenote proof of concept reproduced here
- T2Trail of Bits, 21 April 2025 · Jumping the line: How MCP servers can attack you before you ever use them. Origin of 'line jumping'; the 23 April follow-up demonstrates conversation-history exfiltration via trigger phrases in tool descriptions
- T2Invariant Labs (Milanta, M., & Beurer-Kellner, L.), 26 May 2025 · GitHub MCP Exploited: Accessing private repositories via MCP. Origin of 'toxic agent flows'; cited by OWASP as the GitHub MCP server vulnerability
- T1OWASP Top 10 for LLM Applications 2026 · LLM01:2026 mitigation 10 (pin, sign and verify, and its stated limits), LLM02:2026 Risk #4 (tool descriptions disclosing role requirements), and Scenario #9's three MCP incidents
- T2Radosevich, B., & Halloran, J. (2025). MCP Safety Audit: LLMs with the Model Context Protocol Allow Major Security Exploits (arXiv:2504.03767), cited by OWASP under LLM01
- ·ASI04 Agentic Supply Chain Vulnerabilities is the OWASP entry that owns MCP registries. Its own text sits in the Top 10 for Agentic Applications, which this course does not yet hold, so it is named here only as the pointer OWASP gives