deniz.in

Markets

Weather

Loading weather

· via dev.to (home feed)

MCP tool poisoning hides instructions in tool text that agents read and users never see

Malicious instructions hidden in MCP tool descriptions can make agents read SSH keys and exfiltrate secrets, and most public registries accept poisoned tools without any screening.

MCP tool poisoning hides instructions in tool text that agents read and users never see

How the attack works

The Model Context Protocol lets AI applications discover and call external tools. When an agent connects to a server, each tool arrives with a name, a description and a parameter schema, and the model reads all of that text to work out what the tool does. According to a dev.to write-up on the technique, tool poisoning exploits exactly this arrangement: the attack lives in the description text rather than in the code, so reviewing the code reveals nothing.

The model cannot tell documentation apart from directives. The SlashID research team, cited in the article, points out that nothing in the protocol separates a description that documents a tool from one that commands the model. OWASP's community attack catalogue describes the underlying trust gap: descriptions get reviewed once at connect time, while everything else the server sends flows into the model's context unchecked.

The cleanest documented demonstration came from Invariant Labs in April 2025. A small MCP server exposed a simple addition tool whose code genuinely added two numbers, but whose description carried an embedded instruction block: before calling, read the MCP config file and the SSH private key, pass their contents through a "sidenote" parameter, and do not mention the step to the user. In a documented run against Cursor, the agent treated the hidden block as a legitimate part of the workflow and prepared the call with the sensitive file contents in place — the full chain silently exfiltrated an SSH private key from the session.

The asymmetry is the crux. The model sees the complete description, including the file paths and the instruction to stay quiet, and processes it as ground truth. The user sees an approval dialog reading something like "add — Adds two numbers and returns the sum." The most influential text in the exchange is treated by the interface as mere metadata.

Why it is hard to catch

The article identifies three structural reasons.

First, interfaces hide the payload. Most clients show only a tool's name or a short summary at approval time, so an argument stuffed with file contents never appears on screen.

Second, registries barely screen. OX Security tested eleven public MCP registries and found that nine accepted poisoned tools with zero automated vetting, which makes publishing the attack nearly frictionless.

Third, models comply at high rates. The MCPTox benchmark tested 45 live servers against 20 language models; per a Cloud Security Alliance research note, attacks succeeded 36.5 percent of the time on average and peaked at 72.8 percent against the most vulnerable model. That points to a structural weakness across the ecosystem rather than a single vendor's bug.

A timing variant, the rug pull, shows a benign description when the user approves and swaps in a malicious one afterwards. Most clients ask for consent only once, so the swap may never trigger a second prompt. The Cursor flaw CVE-2025-54136, dubbed MCPoison, exposed the same weakness in configuration form: approval was tied to a server's name rather than its contents, so a committed config could be replaced with a hostile command.

Detection and defences

Invariant Labs, the team behind the original research, released a free scanner called MCP-Scan. It discovers installed MCP servers from Claude, Cursor and Windsurf configurations, pulls every tool description and checks them with local heuristics plus the Invariant Guardrails API, and can be run with a single command. An inspect mode prints the full descriptions so you can read exactly what the model has been reading. The article adds two honest caveats: the Guardrails check sends tool names and descriptions to invariantlabs.ai, so skip it if sharing tool metadata is a concern, and a clean scan is reassuring rather than conclusive since novel phrasings can slip through.

A lightweight supplement is to dump the tool list from each installed server and flag descriptions containing directive patterns such as "ignore previous", "do not mention" or "keep this secret". That catches the known shapes of the attack and pairs well with model-based scanning for reworded variants. Against rug pulls, pinning tool versions prevents a swapped description from silently replacing the one that was approved.

Why it matters

Agents increasingly install tools from public registries with minimal vetting, and the attack surface is the text the model reads rather than the code it executes — meaning traditional code review is blind to it by construction. The measured success rates mean a poisoned tool sitting in a registry is a working exploit against a substantial share of deployments, not a theoretical concern.

The strongest defences are unglamorous: scan before connecting, pin versions, apply least privilege, and keep secrets such as SSH keys and credential-laden config files out of the agent's reach entirely. Until MCP clients render the full text the model sees at approval time, the gap between what the agent reads and what the user approves remains the vulnerability.

  • #mcp
  • #ai-security
  • #prompt-injection
  • #llm-agents
  • #supply-chain

Related posts