CyphrQ

MCP Security Explained: Tool Poisoning, Token Risks and Controls

What the Model Context Protocol is, how MCP servers and tools get abused, real CVEs, and the fixes: allowlists, pinned versions, narrow scopes, approval.

MCP security means controlling what AI assistants can reach through the Model Context Protocol (MCP), an open standard for plugging AI apps into tools and data. Every MCP server you connect can put text in front of the model and act with the access you grant. The protocol can't enforce safety by itself, so the controls are yours: approved servers, pinned versions, narrow permissions, human approval and logs.

What is the Model Context Protocol (MCP)?

The MCP specification calls MCP "an open protocol that enables seamless integration between LLM applications and external data sources and tools." An LLM (large language model) is the engine behind assistants such as ChatGPT, Claude, Copilot and Gemini.

The spec likens it to the Language Server Protocol for code editors: a company publishes one MCP server for its product, and any AI app that speaks MCP can use it.

Messages travel as JSON-RPC 2.0. This post follows the spec revision dated 2026-07-28, checked on 25 October 2026.

How do MCP hosts, clients, servers and tools fit together?

Part How the spec defines it Everyday example
Host "LLM applications that initiate connections" An AI chat app or AI coding editor
Client "Connectors within the host application" The piece inside the app that talks to one server
Server "Services that provide context and capabilities" A connector for email, files or a database

Servers can offer three things: resources ("context and data"), prompts ("templated messages and workflows") and tools ("functions for the AI model to execute").

Tools are where security gets real. The tools page says they are "model-controlled": the model "can discover and invoke tools automatically." The client asks a server for its tool list, each with a name, a plain-text description and an input schema, and the model uses those descriptions to decide what to call.

Servers run in two places. A local server is a program on your own machine; the spec recommends it talk to the app over standard input and output (stdio). A remote server sits on the internet and is reached over HTTP, where the spec's optional OAuth-based authorization applies.

What are the main MCP security risks?

The spec's overview admits that "MCP itself cannot enforce these security principles at the protocol level." Five risks stand out.

Tool poisoning: hidden instructions in MCP tool descriptions

Tool poisoning is prompt injection delivered through the tool list. Invariant Labs named it on 1 April 2025: "malicious instructions are embedded within MCP tool descriptions that are invisible to users but visible to AI models."

The same research describes two variants. In a rug pull, "a malicious server can change the tool description after the client has already approved it." In shadowing, one server's description changes how the agent uses a different, trusted server's tool, such as an email tool.

The spec agrees on the principle: tool descriptions and annotations "should be considered untrusted, unless obtained from a trusted server." For how injected instructions work in general, see the prompt injection explainer.

Untrusted community MCP servers

Anyone can publish an MCP server, and some are distributed through public package registries such as npm.

In practice: on 25 September 2025, Postmark warned that an npm package called postmark-mcp was impersonating it. Postmark says the package "built trust over 15 versions, then added a backdoor in version 1.0.16 that secretly BCC'd emails to an external server." It adds: "We have not published our Postmark MCP server on npm prior to this incident."

The lesson is about provenance. Fifteen clean releases proved nothing, because the publisher was never Postmark.

Local MCP servers running with your user rights

A local server is ordinary software. The security best-practices page warns that such servers "may have direct access to the user's system" and that attackers "can execute any command with MCP client privileges." It tells clients to "warn that MCP servers run with the same privileges as the client."

In plain terms: a local server can typically read what you can read, including files, keys and saved credentials. The spec's authorization rules also say stdio servers should "retrieve credentials from the environment", so secrets set there are within its reach.

Over-broad MCP tokens

Remote servers use OAuth access tokens. The best-practices page describes an attacker obtaining a token "carrying broad scopes (files:*, db:*, admin:*)" because the client asked for everything up front. Its listed risks include an "expanded blast radius" and "privilege chaining", where the attacker can call high-risk tools straight away.

Confused deputy and token passthrough in MCP

A confused deputy is a trusted program tricked into using its authority for someone else. The spec describes it for MCP proxy servers that front a third-party API with one fixed OAuth client ID. If the third party remembers consent in a cookie and the proxy skips its own per-client consent step, an attacker can obtain an authorization code without the user really approving. The fix: proxies "MUST implement per-client consent."

Token passthrough is the spec's name for "an anti-pattern where an MCP server accepts tokens from an MCP client without validating that the tokens were properly issued to the MCP server" and forwards them downstream. It muddies audit trails and lets a stolen token use the server as a relay. The rule is blunt: "MCP servers MUST NOT accept any tokens that were not explicitly issued for the MCP server."

Which controls reduce MCP security risk?

Here are five controls, roughly in the order a team would deploy them. They line up with the spec and with OWASP's LLM06:2025 Excessive Agency mitigations, such as "Minimize extensions" and "Require user approval".

  1. Allowlist MCP servers. Keep a short list of approved servers per team, each with an owner and a reason, and block the rest. Unapproved connectors are a form of shadow AI, so look for them the same way.
  2. Pin versions and verify the publisher. Invariant Labs advises that clients "pin the version of the MCP server and its tools to prevent unauthorized changes," with a hash or checksum. Pinning stops a new malicious release reaching you silently. The Postmark case shows its limit: also confirm the package is listed in the vendor's own documentation.
  3. Grant least-privilege scopes. The authorization spec says clients "SHOULD follow the principle of least privilege by requesting only the scopes necessary." Start read-only and grant write access when a task needs it.
  4. Keep a human in the loop for actions. The tools page: "there SHOULD always be a human in the loop with the ability to deny tool invocations." Be wary of "always allow" on any tool that sends, deletes, pays or shares. The wider case for approval gates is in the AI agents guide.
  5. Log tool use. The spec says clients should "log tool usage for audit purposes." Record which server and tool ran, with what inputs, and who approved it.

What should you check before connecting an MCP server?

  • Who publishes it, and does the vendor's own documentation link to it?
  • Is the version pinned, and will an update need review before it runs?
  • Does it run locally with your rights, or remotely with its own OAuth token?
  • Which scopes does it ask for, and could it work with fewer?
  • Do its tool descriptions read like instructions to the AI rather than descriptions for you?
  • Which of its tools can act, and do those ask before acting?

More on this topic: the AI Security section.

Going deeper: for security and IT teams

Identifiers. Map MCP findings to OWASP LLM06:2025 Excessive Agency, which names excessive functionality, permissions and autonomy. The CVEs below carry CWE-78, CWE-306 and CWE-59. The authorization spec builds on RFC 8707 (resource indicators), RFC 9728 (protected resource metadata), RFC 9207 (issuer identification) and RFC 6750 (bearer tokens).

Trust boundaries. Three server-controlled inputs cross into the client. Tool descriptions land in model context. OAuth discovery URLs (resource_metadata, authorization_servers, token and authorization endpoints) get fetched by the client, which the spec flags as an SSRF path to targets like 169.254.169.254. And the authorization URL gets opened by the client.

Threat model. Attackers include a malicious or hijacked server publisher, anyone holding a leaked token, and a web page reaching a local server left listening on localhost through DNS rebinding. Their gain is capped by host privileges, token scopes and which tools run unapproved.

In practice: documented MCP CVEs (CVE records read through the CVE Program's API on 25 October 2026):

CVE Component What the record says Score Fixed
CVE-2025-49596 MCP Inspector RCE "due to lack of authentication between the Inspector client and proxy"; published 13 June 2025 CVSS 4.0: 9.4, CWE-306 0.14.1
CVE-2025-53109 Filesystem server "could allow access to unintended files via symlinks"; published 2 July 2025 CVSS 4.0: 7.3, CWE-59 0.6.4 or 2025.7.01
CVE-2025-6514 mcp-remote 0.0.5 to 0.1.15 "OS command injection when connecting to untrusted MCP servers" via the authorization_endpoint URL; published 9 July 2025 CVSS 3.1: 9.6, CWE-78 Patch commit linked; no version named

CVE-2025-6514 is the class the spec's "OAuth Authorization URL Validation" section covers: clients "MUST NOT use shell commands" to open URLs and must reject javascript:, data:, file: and vbscript: schemes.

Controls with specifics.

  • Servers: validate audience per RFC 8707 Section 2 and return 401 for invalid tokens. Never forward client tokens. Answer missing permissions with 403 and WWW-Authenticate: Bearer error="insufficient_scope", scope="...". Avoid wildcard scopes; the spec's example minimal scope is mcp:tools-basic.
  • Clients: send the resource parameter in authorization and token requests. Require HTTPS, and block 10.0.0.0/8, 172.16.0.0/12, 192.168.0.0/16, 127.0.0.0/8 and 169.254.0.0/16 for OAuth fetches. Route discovery through an egress proxy.
  • Proxies: store per-user approved client_id values. Match redirect_uri exactly. Use __Host- consent cookies with Secure, HttpOnly and SameSite=Lax, and single-use state values.
  • Local servers: prefer stdio over an open localhost HTTP port. Before one-click installs, show "the exact command that will be executed, without truncation." Sandbox the process with no default network or home-directory access.

Detection. Log every tools/call with server, tool, arguments, approver and result size. Hash each tool description at approval, and alert when a notifications/tools/list_changed brings a changed hash; that is a possible rug pull. Alert on MCP clients reaching private ranges, bursts of insufficient_scope, and scope elevation events, which the spec says to log "with correlation IDs." Test in a lab: point a client at a server whose description holds a harmless instruction and see whether the model follows it.

Ask vendors: do you show full tool descriptions and flag changes? Can admins enforce a server allowlist? Do local servers run sandboxed?

Learn more

Key takeaways

  • Every MCP server's tool descriptions reach the model, so treat them as untrusted input.
  • Tool poisoning hides instructions in those descriptions; a rug pull changes them after approval.
  • Local servers typically run with your rights. Remote servers need narrow tokens issued only for them, and the spec forbids token passthrough.
  • Allowlist servers, pin versions, verify publishers, grant minimal scopes, approve actions and log tool calls.

Sources