The tool is called screenshot-page. It takes a URL and returns a picture of the rendered page. Its only input check is that the argument parses as a URL, so file:/// URLs pass, and the tool renders local files from the machine it runs on. Plain http:// URLs pointed at internal services pass too, which makes it a server-side request forgery (SSRF) tool. “Type checks and crash detection see a healthy tool,” the authors of a new preprint write. “Only the word ‘webpage’ puts file: out of contract.”1
That case, from webpage-screenshot-mcp, is the clearest example in ToFu, a fuzzing study of Model Context Protocol (MCP) servers posted to arXiv on October 9.1 The first coverage led with the count: 253 bugs across 343 AI agent tools.2 The count is real, but it isn’t the finding. ToFu’s useful result is systematic, hand-verified evidence that MCP tools treat a schema-valid argument (one with the right types and shape) as a safe one. That breaks a rule the MCP spec already has, and it’s the same mistake that keeps showing up in individually reported CVEs.
What We Know
What ToFu actually did
ToFu (preliminary results, not yet peer-reviewed) treats every argument an LLM passes to a tool as attacker-controlled. Its threat model is an agent steered by injected content.1 For each tool, gpt-4.1 reads the name, description and input schema and picks from 74 CWE-guided sanitizers, checks that fire when an input breaks a security property the description implies. The LLM doesn’t judge bugs. Runtime tracers that hook file, process and socket calls do, along with outcome checks that flag adversarial input the tool accepted without complaint. Each tool then gets 60 seconds of coverage-guided fuzzing with Atheris inside a bubblewrap sandbox, and the authors triaged every candidate by hand.1
The headline numbers make sense only with their funnel:
| Stage | Count |
|---|---|
| Repositories exposing at least one tool | 1,404 |
| Built and listed tools over stdio | 482 |
| Returned a successful call (the evaluated set) | 273 |
| Candidate bugs flagged | 508 |
| Rejected on manual review / duplicates removed | 103 / 152 |
| Verified bugs | 253 |
| Tools those bugs affect | 343 |
| Servers with at least one verified bug | 118 |
So 118 is 43% of the servers ToFu could actually run. It’s about 8% of the servers that expose tools at all, because 81% of those never reached the evaluated set. Most failed to build or needed credentials and backends the fuzzer didn’t have.1 Neither percentage tells you how much of the MCP ecosystem is vulnerable.
Most of the bugs are low-severity
Table 3 of the paper breaks down the 253 verified bugs:1
| Bug class | CWE | Count |
|---|---|---|
| Reflected or unescaped output | 116/79 | 115 |
| Path traversal | 22 | 64 |
| Log injection | 117 | 58 |
| SSRF | 918 | 7 |
| Data exfiltration | 201 | 5 |
| OS command injection | 78 | 3 |
| Leftover temp file | 459 | 1 |
Reflected output and log injection account for 173 of the 253, or 68%. Three bugs are command injection. Cyber Press, one of the two outlets that covered the paper, called the results “implementation weaknesses in tested servers, not proof of compromise across deployed environments.”2 That’s a fair reading. It’s also why the low-severity mix strengthens the main point rather than weakening it. None of these bugs needs a clever exploit. They come from tools that never checked what their own descriptions promised.
The minority classes are concrete, though. Fuzzing alone caused real side effects on the host: one server deleted files outside its workspace, and another killed tmux sessions it didn’t own.1 The authors use that to argue for running tool fuzzers in a sandbox, which is good advice for anyone pointing an agent at a third-party MCP server too.
The same root cause, found independently
ToFu didn’t discover this bug pattern. It measured it at scale. Hand-found CVEs show the same failure, including in Anthropic’s own reference servers:
- The reference filesystem server checked paths with a string prefix and followed symlinks out of the allowed directory (CVE-2025-53109 and CVE-2025-53110, fixed in 2025.7.01).3
- The reference git server passed a model-supplied ref straight to
git, so a value like--output=…became a flag that could overwrite files (CVE-2025-68144, fixed in 2025.12.18).4 - The Framelink Figma server put a model-supplied file key into an
execshell string (CVE-2025-53967, fixed in 0.6.3).5 - A week before ToFu, The Next Web reported one researcher’s SSRF findings in MCP servers from Google, JPMorgan, Weaviate and two government bodies, which fixed them, and said servers run by the US General Services Administration were still unfixed.6
Here is the filesystem mistake and its fix, run on Node 22:
import { realpath } from "node:fs/promises";
import path from "node:path";
// Vulnerable: "/srv/data-secrets/key.txt" starts with "/srv/data",
// and a symlink inside the root is never resolved.
function naiveInside(root: string, requested: string): boolean {
return path.resolve(root, requested).startsWith(root);
}
// Fixed: resolve symlinks, then compare on a separator boundary.
async function resolveInside(root: string, requested: string): Promise<string> {
const base = await realpath(root);
const target = await realpath(path.resolve(base, requested));
if (target !== base && !target.startsWith(base + path.sep)) {
throw new Error(`path escapes ${base}`);
}
return target;
}
Against a sibling directory called data-secrets and a symlink inside data, the naive check allowed both escapes and the fixed version rejected both. The fix still has a gap ToFu can’t see: a file can change between the check and the open.
Why the schema doesn’t save you
The MCP spec is explicit. Under “Servers MUST,” the first item is “Validate all tool inputs.”7 An input schema helps with that, but JSON Schema describes types, enums, patterns and lengths. It has no way to say “this path must stay inside the root after symlinks,” “this host must not be private,” or “this string must not start with a dash.” Those rules live in a tool’s description as English, and ToFu shows that many servers never turn that English into code.
That makes this ecosystem non-compliance, not a protocol flaw. It also cuts against the comforting idea that a well-behaved client stops bad calls. The paper’s Repeat-After-Me attack builds text that looks like a tool call and asks the model to repeat it, and the orchestrator executes it. The authors report reproducing it in six frameworks, including LangGraph, Google ADK and CrewAI. Only the LangGraph run is shown, with llama3.1:8b and stub tools.1 That isn’t evidence that frontier agents fall for it, but the authors’ reproductions suggest you can’t count on the orchestration layer to catch it.
Consensus: schema validation is a type contract, not a security contract. ToFu’s data, Anthropic’s reference-server CVEs and the spec’s own wording all point the same way.
Active disagreements:
- An LLM code audit kept pace with the fuzzer. On the same 273 servers, a plain Claude Sonnet 5 review flagged 119 servers to ToFu’s 118, and only 8 servers were flagged by ToFu and no baseline.1 The authors decline to rank the tools because they measure different things.
- Prevalence estimates don’t agree. ToFu’s 43% of reachable servers sits next to 7.2% of 1,899 servers in a static study and roughly 0.3% for VIPER-MCP’s three taint classes.89 Different methods, classes and denominators make these numbers incomparable, and none of them answers “how much of MCP is broken.”
- Some of this may be “working as intended.” OX Security called stdio command execution in the official SDKs a systemic vulnerability. Obsidian Security and the spec say stdio isn’t inherently a vulnerability.1011 ToFu itself didn’t count one tool whose documented job is running code.
- ToFu called tools directly. No real client was in the loop, so it doesn’t show that a production agent emits these arguments, or that permission prompts fail to stop them.
The paper is also candid about its noise. The set of bugs found varied between runs (pairwise Jaccard overlap of 0.75 to 0.81), and with every sanitizer switched on only 4.9% of reports were real.1 Manual review is why the 253 is credible. Another study found that existing MCP scanners flagged 96.89% of servers as risky, with fewer than half of sampled alerts holding up.12 An unverified scanner number tells you very little. Defenses fall short too: the SSRF fixes in meta-ads-mcp and the reference fetch server both say they don’t stop DNS rebinding.13
Open Questions
- Were the 253 bugs disclosed to the 118 maintainers, and have any been fixed?
- Does reflected tool output, the largest class, lead to a second-stage prompt injection when it flows back into a real client’s context?
- How often does a frontier agent under indirect prompt injection actually emit path-traversal or SSRF arguments, and how often do client permission prompts stop it?
- Were the Table 4 baseline flags, including the Sonnet 5 audit, verified by hand the way ToFu’s were?
- What changes when the 81% of servers that need credentials or backends get fuzzed? Those are plausibly the most widely deployed ones.
Next Steps
For anyone shipping an MCP server, the checklist is short and none of it is new:
- Re-validate meaning in the handler, not just shape in the schema.
- Resolve real paths and compare on a separator boundary, as above.
- Reject arguments that start with
-before they reach a CLI, or pass--first. - Use
execFilewith an argument array, never a shell string. - Resolve hostnames and re-check private ranges on every redirect, and know that it still won’t stop DNS rebinding.
- Return
isError: truewhen you reject an input, so the model sees why. - Search your tool descriptions for “within,” “only” and “allowed,” and confirm each one has a matching check in code.
Next, I want to reproduce the webpage-screenshot-mcp case in a sandbox with no credentials and see whether it still renders local files today. That would turn the paper’s best example into something you can run. I’m also writing to the authors about disclosure.
Angles I might be missing: if you maintain an MCP server and heard from the ToFu team, or you’ve measured whether real clients block these arguments, I’d like to hear from you.
Footnotes
-
Ananto, Prevost-Avenel, Smith, K. Kim, T. Kim, and Khan. “ToFu: Exploiting and Fuzzing the LLM-Orchestrator-Tool Trust Boundary.” Preprint, not peer-reviewed. arXiv:2610.13651, October 9, 2026. arxiv.org/abs/2610.13651. ↩ ↩2 ↩3 ↩4 ↩5 ↩6 ↩7 ↩8 ↩9 ↩10 ↩11
-
Cyber Press. “Researchers Find 253 Security Bugs Across 343 AI Agent Tools in MCP Servers.” October 13, 2026. cyberpress.org/researchers-find-253-security-bugs-343-ai-agent-tools. ↩ ↩2
-
Cymulate. “EscapeRoute: CVE-2025-53109 and CVE-2025-53110.” Vendor research. cymulate.com/blog/cve-2025-53109-53110-escaperoute-anthropic. Advisories: github.com/modelcontextprotocol/servers/security/advisories. ↩
-
The Hacker News. “Three Flaws in Anthropic MCP Git Server.” January 20, 2026. thehackernews.com/2026/01/three-flaws-in-anthropic-mcp-git-server.html. ↩
-
GitHub Advisory Database. “GHSA-gxw4-4fc5-9gr5: figma-developer-mcp command injection (CVE-2025-53967).” github.com/advisories/GHSA-gxw4-4fc5-9gr5. ↩
-
The Next Web. “Google, JPMorgan and two governments fixed the same MCP flaw.” October 6, 2026. thenextweb.com/news/mcp-flaw-ssrf-google-jpmorgan-dinum-protocol-pivoting. ↩
-
Model Context Protocol. “Specification 2026-07-28: Tools.” modelcontextprotocol.io/specification/2026-07-28/server/tools. ↩
-
Sun et al. “VIPER-MCP: Detecting and Exploiting Taint-Style Vulnerabilities in Model Context Protocol Servers.” Preprint. arXiv:2605.21392. arxiv.org/abs/2605.21392. ↩ ↩2
-
Hasan et al. “Model Context Protocol (MCP) at First Glance: Studying the Security and Maintainability of MCP Servers.” Preprint. arXiv:2506.13538. arxiv.org/abs/2506.13538. ↩
-
OX Security. “The Mother of All AI Supply Chains.” Vendor research, April 15, 2026. ox.security/blog/the-mother-of-all-ai-supply-chains-critical-systemic-vulnerability-at-the-core-of-the-mcp. ↩
-
Obsidian Security. “When is stdio MCP actually a vulnerability?” obsidiansecurity.com/blog/when-is-stdio-mcp-actually-a-vulnerability. ↩
-
Chen et al. “Rethinking MCP Security: A Large-Scale Study of Runtime MCP Servers and Security Scanner Reliability.” Preprint. arXiv:2607.11086. arxiv.org/abs/2607.11086. ↩
-
OSV. “PYSEC-2026-3485: meta-ads-mcp SSRF (CVE-2026-54549).” osv.dev/vulnerability/PYSEC-2026-3485; Model Context Protocol. “Fetch MCP Server” README. github.com/modelcontextprotocol/servers/tree/main/src/fetch. ↩