Skip to content
MoorAI
// blog · Damn Vulnerable MCP

Damn Vulnerable MCP: 9 of 10 blocked outright, 10 of 10 with IP exposure set to block

All ten DVMCP challenges, unmodified, behind the MoorAI MCP guard and gateway on the device. Content-free, with no LLM in the loop.

Diagram titled Damn Vulnerable MCP: 9 of 10 blocked outright. 10 of 10 with intellectual-property exposure (#9) set to block; ten unmodified DVMCP challenges behind MoorAI, on one device, with no LLM in the loop. Three surfaces: the MCP stdio guard, 9 of 10 blocked, 10 of 10 with #9 set to block; the MCP HTTP gateway, the same; the Claude Code hook alone, 5 of 10 blocked, 1 flagged and 4 missed, with no hook event for tool descriptions or resource reads. Each challenge at the guard and gateway, with the rules that stop it: C1 prompt injection, blocked, #3, #40 and #39; C2 tool poisoning, partial, #60 refused and #9 flagged; C3 path traversal, blocked, #39 file read refused; C4 rug pull, blocked, tool drift and #60; C5 tool shadowing, blocked, #60 and #39; C6 indirect injection, blocked, #3 and #39; C7 token theft, blocked, #39 withheld; C8 code execution, blocked, #39 withheld; C9 command injection, blocked, #54 before it runs; C10 multi-vector, blocked, #60, #39 and #40. Below: guard and gateway cover the MCP layer, content-free: tool listings, tool calls, tool results and resource reads, judged on the device; route MCP traffic through them. 1 of 19 benign calls refused: a call to a tool whose description was poisoned, quarantined by design. Damn Vulnerable MCP: 9 of 10 blocked outright 10 of 10 with intellectual-property exposure (#9) set to block. Unmodified challenges, one device, no LLM. MCP STDIO GUARD 9 / 10 blocked 10 / 10 with #9 set to block MCP HTTP GATEWAY 9 / 10 blocked 10 / 10 with #9 set to block CLAUDE CODE HOOK ALONE 5 / 10 blocked 1 flagged · 4 missed: no hook event C1 BLOCKED Prompt injection #3 · #40 · #39 C2 PARTIAL Tool poisoning #60 refused · #9 flagged C3 BLOCKED Path traversal #39 file read refused C4 BLOCKED Rug pull tool drift · #60 C5 BLOCKED Tool shadowing #60 · #39 C6 BLOCKED Indirect injection #3 · #39 C7 BLOCKED Token theft #39 withheld C8 BLOCKED Code execution #39 withheld C9 BLOCKED Command injection #54 before it runs C10 BLOCKED Multi-vector #60 · #39 · #40 GUARD AND GATEWAY: THE MCP LAYER, CONTENT-FREE Tool listings, tool calls, tool results and resource reads, judged on the device. Route MCP traffic through them. 1 of 19 benign calls refused: a call to a tool whose description was poisoned, quarantined by design. AI security at the point. · Open source · MIT · moorai.dev MoorAI

Damn Vulnerable MCP (DVMCP) is ten deliberately vulnerable MCP servers that show how an AI agent gets attacked through the tools it trusts: prompt injection, tool poisoning, a rug pull, tool shadowing, token theft, code execution, command injection and a chained multi-vector attack. MoorAI ran all ten, unmodified. The MoorAI MCP guard and the MoorAI MCP gateway each blocked 9 of 10 outright: every exploit attempt refused or withheld on the device, before it reached the data. In the tenth, tool poisoning, both poisoned tools were refused and the read of the server’s hidden resource was flagged as intellectual-property exposure (#9). With #9 set to block, the guard and the gateway each block 10 of 10.

MoorAI agent v1.22.0 on DVMCP, ten challenges
9/10MCP stdio guardBlocked outright; 10/10 with #9 set to block
9/10MCP HTTP gatewayBlocked outright; 10/10 with #9 set to block
1 of 19benign calls refusedA call to a poisoned tool, quarantined by design
0LLMs in the loopContent and transport layer, content-free capture

The benchmark, and who built it

DVMCP is the work of Harish SG, who presented it with Ankit Garg in a SecTor talk. It turns MCP attacks into ten servers anyone can run, each with a working exploit, which is exactly what a defender needs to test against. It is open source under MIT at github.com/harishsg993010/damn-vulnerable-MCP-server. Thank you to both for building it and sharing it.

Ten challenges, challenge by challenge

#AttackGuardGatewayHook aloneWhat stops it
1Prompt injection in a resourceBlockedBlockedMissed#3 and #40 refuse the injected result; #39 withholds the credentials resource
2Tool poisoningPartialPartialMissed#60 refuses every call to both poisoned tools; #9 flags the hidden-resource read, and withholds it when set to block
3Excessive permission scopeBlockedBlockedBlocked#39 refuses the read of the credentials file
4Rug pullBlockedBlockedMissedTool drift against the approved baseline quarantines the changed tool
5Tool shadowingBlockedBlockedMissed#60 quarantines the shadowing tool; #39 withholds the secrets resource
6Indirect prompt injectionBlockedBlockedBlocked#3 refuses the document carrying the directive; #39 withholds the labeled API keys
7Token theftBlockedBlockedBlocked#39 withholds the JWT and API key in tool results
8Malicious code executionBlockedBlockedBlocked#39 withholds AWS keys and passwords from shell and Python output
9Remote access, command injectionBlockedBlockedBlocked#54 refuses the injected argument and the reverse shell before the tool runs
10Multi-vectorBlockedBlockedFlagged#60 quarantines the poisoned and shadowing tools; #39 withholds the token and the admin credentials

What stops what, at the MCP layer

Tool poisoning and shadowing · #60 · challenges 2, 5, 10

A tool whose description carries hidden instructions, or that shadows a trusted tool, is flagged at tools/list and quarantined: it stays in the listing, and every call to it is refused, whatever the arguments.

In challenge 2 the hidden instructions point at an unlisted company://confidential resource. MoorAI flags a read of it as intellectual-property exposure (#9), which notifies in the Regulated preset. Set #9 to block and the read is withheld, while the server’s public resource still passes.

Rug pull · tool drift · challenge 4

The tool’s description mutates after a few calls. Each server’s initial tool list is the approved baseline, so the changed tool drops out of the next listing and its call is refused until an admin re-approves it.

Secrets in results · #39 · challenges 3, 5, 6, 7, 8, 10

AWS keys, JWTs and provider tokens are withheld from tool and resource results, and so are credentials written as labeled text, such as “Master Password: …” or “Main API: …” under a credentials heading. Reads of credential files are refused.

Injected directives · #3 and #40 · challenges 1, 6, 10

Instructions planted in a tool result, a resource or an ingested document are refused before the agent reads them.

Command injection · #54 · challenge 9

A host value with a shell command appended, and a reverse shell, are refused in the tool argument, before the tool runs.

The evaluation drove two new detectors, both shipping in agent v1.22.0: credentials written as labeled text (challenge 6) and command injection in MCP tool arguments (challenge 9). Benign false-positive rates are unchanged on the benign corpora.

The hook sees calls. The guard and gateway see MCP.

As a Claude Code hook alone, MoorAI blocked 5 challenges, flagged 1 and missed 4. The four (challenges 1, 2, 4 and 5) carry the attack in a tool description or an MCP resource read, and Claude Code gives a hook no event for either. Tool descriptions and resource reads are visible only to the guard and the gateway.

So route MCP traffic through the MoorAI guard (stdio) or gateway (HTTP). Both judge the whole MCP conversation on the device: tool listings, tool calls, tool results and resource reads.

Benign traffic keeps flowing

Alongside the exploits, the run sent 19 benign calls. The guard refused one: a call to a challenge 2 tool whose description is poisoned. MoorAI quarantines the whole poisoned tool by design, so its legitimate uses stop with it. Every other benign call went through, and with #9 set to block the count stays at 1 of 19.

Questions to ask any MCP security tool

MoorAI does each of these today, on the device, with the per-challenge results to show it.

How the run worked

Coverage today

The guard and the gateway cover the MCP layer: tool listings, tool calls, tool results and resource reads. A poisoned tool stays in the listing the agent receives, and every call to it is refused; only drift-block mode withholds a changed tool from the listing. Intellectual-property exposure (#9) notifies in the Regulated preset and blocks when set to block. A Claude Code hook receives tool calls and their results, not tool descriptions or resource reads. This run exercised stdio and streamable HTTP; SSE was not part of it.

Sources

DVMCP is an independent open-source project by Harish SG. MoorAI ran it as published; the results here are MoorAI’s own.


See also: MCP security, Claude Code security and hidden Unicode in what AI agents read.

Put your MCP servers behind the guard.
On-device guardrails for AI agents: tool poisoning, rug pulls, leaked secrets and command injection stopped at the MCP layer. Open source under MIT.
Get started free → Ask for the per-challenge results