
Five MCP attack patterns every developer should understand: tool poisoning, supply chain attacks, localhost RCE, rug pulls, and overprivileged access. Real CVEs and mitigations for each.
MCP is one of the more exciting things to happen to developer tooling in a while. And like most things that get adopted quickly, the security thinking tends to lag behind the enthusiasm.
Servers are distributed through npm and PyPI, permissions are broad by default, and the protocol doesn't enforce authentication or integrity checks out of the box. None of that is a reason to avoid MCP. It's just worth understanding before you wire it into your stack.
Here are the five attack patterns worth understanding, with real CVEs, proof-of-concept examples, and mitigations for each.
A malicious MCP server can embed hidden instructions in its tool descriptions that manipulate the LLM into doing things you never asked for. The instructions don't show up in the tool's visible behavior. They sit in the context window where the model reads them as legitimate guidance and acts accordingly.
Example: Researchers demonstrated that a malicious MCP server could silently exfiltrate a user's entire WhatsApp message history by combining a poisoned tool with a legitimate whatsapp-mcp server running in the same agent. The same technique pulled contents from private GitHub repositories via compromised personal access tokens.
How to prevent it:
MCP servers are distributed through npm, PyPI, and GitHub with no centralized vetting. Anyone can publish one. Most developers install them based on a README and a star count, which is roughly the same due diligence you'd apply to choosing a restaurant.
Example: CVE-2025-6514 (CVSS 9.6): the mcp-remote package, downloaded 437,000+ times, trusted server-provided OAuth endpoints without validation. An attacker could craft a malicious authorization URL that gets executed directly by the system's shell, achieving full remote code execution on any machine running the package.
How to prevent it:
If an MCP development tool binds to localhost without authentication, any webpage you visit can talk to it. No phishing, no downloads. Just a browser tab open while you're working.
Example: CVE-2025-49596 (CVSS 9.4): Anthropic's own MCP Inspector launched a web UI on localhost with no authentication. A malicious webpage could inject commands into the Inspector's proxy, achieving RCE on the developer's machine. At the time of disclosure, 560 exposed MCP Inspector instances were found on Shodan.
How to prevent it:
An MCP server can change its tool descriptions after you've already approved it. The initial install looks clean. The descriptions pass review. Then the server quietly updates its tool definitions to include malicious instructions, and your agent executes them with the permissions you already granted. Think of it as a bait and switch at the protocol level.
Example: This is a documented attack pattern. The official MCP specification acknowledges that servers can modify tool definitions between invocations. There is no built-in mechanism to detect or prevent this.
How to prevent it:
Most MCP servers request far more permissions than they need. A single server token might grant access to email, calendars, file storage, databases, and source code all at once. If that server gets compromised or its tool is poisoned, the attacker inherits every one of those permissions. There's also the confused deputy problem: an MCP server performs actions with its own elevated permissions rather than the user's, which can expose resources the user was never supposed to reach.
Example: An MCP server granted a personal access token with full GitHub org access. If that server's tool descriptions are poisoned (attack #1) or it receives a rug pull update (attack #4), the attacker now has read/write access to every repository in the org.
How to prevent it:
The mitigations above are per-attack-pattern. Here are the systemic practices that cover your entire MCP surface area.
Audit before you install. Read the source code. Check the tool descriptions. Look at what permissions it requests and whether those permissions match what the tool actually needs. If a server asks for write access to your filesystem and it's supposed to read calendar events, that's a problem.
Pin and hash. Lock your MCP server versions and tool definitions. If a server changes its tool descriptions between sessions, you want to know about it before your agent acts on the new instructions.
Scope credentials narrowly. One MCP server should not have a token that grants access to your entire GitHub org, your Supabase database, and your email. Separate concerns. One server, one set of minimally scoped credentials.
Monitor MCP traffic. Log what tools your agents call, what data they send, and what responses they receive. If an agent starts sending data to an unexpected endpoint, you need to know immediately.
Follow the spec. The official MCP security best practices include requiring user confirmation for sensitive operations and implementing proper consent flows. Read it. Most developers haven't.
That's a lot of surface area to cover manually, especially as the number of MCP servers in your environment grows. An all-in-one security solution like Fencer can help you cover your essentials and steer clear of common MCP risks such as tool poisoning, supply chain vulnerabilities, rug pull mutations, and issues related to overprivileged access, so you're not relying on manual audits to catch the risks that matter most.