ToFu: Exploiting and Fuzzing the LLM–Orchestrator–Tool Trust Boundary
ToFu is a tool-aware fuzzing framework that derives semantic security checks for LLM tools (mainly MCP servers) from their metadata and a corpus of 74 CWE-guided sanitizers. It generates schema-valid Atheris harnesses, uses runtime tracers and outcome oracles to catch bugs that don't crash, and uses an LLM only to map sanitizers and seed inputs, never as the judge. It also describes a "Repeat-After-Me" attack, in which the LLM is told to repeat attacker-written text that the orchestrator then dispatches as a tool call. It was reproduced on LangGraph, MAF, ADK, AutoGen, Strands and CrewAI. On 273 MCP servers it reports 253 verified bugs across 343 tools in 118 repositories, including path traversal, log injection, exfiltration and command bypass.
What it is
ToFu is a Python fuzzing framework (built on Atheris/libFuzzer, with a JS runner) that tests LLM tool implementations, mainly MCP servers, against security contracts derived from each argument's own metadata. It adds oracles for bugs that return normally instead of crashing. The page's real value for an engineer is what it says about which bug classes are common, what the tool misses, and how to run this kind of test safely.
How it works
- An LLM does two jobs per tool: it picks sanitizers from the 74-entry corpus, and it adapts seed payloads to the tool's schema. It never judges a result.
- Introspector sanitizers read events from 21 Python tracers hooked on sinks such as
open,subprocessandsocket. Outcome sanitizers flag an adversarial input and report a bug if the tool returns success. - For each selected outcome sanitizer, the LLM writes an
on_triggerrule:raise_exception,allow_success_with_fallback, orallow_success_always. - Of the 74 sanitizers, 11 always run, 35 run when their evidence appears, and 27 run only when the LLM selects them.
Findings that change what you check
Verified bug classes, from the page's breakdown of the 253 bugs:
| Class | Count |
|---|---|
| Reflected output | 115 |
| Path traversal | 64 |
| Log injection | 58 |
| SSRF | 7 |
| Data exfiltration | 5 |
| OS command injection | 3 |
| Leftover temp file | 1 |
- At the 60 s per-tool budget, ToFu finds 231 of the 253 bugs. The other 22 need runs of between 111 s and 70 minutes.
- Of 508 initial candidates, 326 showed the dangerous operation or an unescaped value directly. In the other 182 the input violated a constraint but the tool simply reported success.
- Baselines on the same 273 servers:
| Analyzer | Servers flagged |
|---|---|
| ToFu | 118 |
| Claude Sonnet 5 audit | 119 |
| CodeQL sec-extended | 95 |
| VIPER-MCP taint stage | 48 |
| Cisco MCP Scanner | 46 |
- VIPER-MCP's agent stage confirmed exploits in 11 servers. ToolFuzz flagged 92 servers, but it tests documentation correctness, not security. Eight servers were flagged only by ToFu.
- The page reports agreement on shared arguments (path traversal, command injection) and says the analyzers otherwise measure different things.
Preconditions / Affected
- The tool must actually execute. Of 482 buildable servers, only 273 were cleanly executable, with no missing credentials or backends. Sitecore ran 123 tools but only one succeeded.
- Introspection covers in-process Python targets only. JavaScript targets get outcome checks only.
- The page names six orchestrators where Repeat-After-Me reproduced: LangGraph, MAF, ADK 2.0, AutoGen, Strands and CrewAI. The attacker needs to know the orchestrator's tool-call format.
What to do
- Treat every schema-valid argument as attacker-controlled, and validate paths, URLs and commands inside the tool. Don't rely on the LLM or orchestrator.
- Fuzz inside a sandbox. The page used bubblewrap with a read-only root and a private
/tmp. Four servers affected the host during fuzzing: - UltimateCoderMCP deleted files outside its workspace.
- obsidian-mcp followed a fuzzed path outside its vault.
- tmux-mcp killed sessions it did not own.
- DesktopCommanderMCP spawned processes without limit.
- Don't enable all 74 sanitizers on every tool. Doing so more than doubled reports, and over 90% were false on the tools only that arm flagged. Throughput was unchanged at about 43 executions per second.
- Supply valid identifiers and credentials as seeds, since unreachable logic is the main miss. About 63% of baseline-flagged servers that ToFu missed failed at startup or rejected every input early.
- Pair it with static tools. About a fifth of baseline-only servers had permissive CORS, bad sanitizing regexes or filesystem races.
Caveats
- The 253 bugs were hand-verified, but the page gives no disclosure or fix status.
- Selection misses real bugs. The all-sanitizers run found 13 that ToFu missed in five servers, including five SSRF in one WordPress server. The LLM chose a Python-only SSRF tracer for a JS target.
- Intentional code runners (
python_repl,applescript_execute) are not flagged by design. VIPER-MCP counted these as exploits. - Replication is noisy. Across three full runs, only 342 bugs appeared in all three, with Jaccard overlap of 0.75–0.81 between runs.
- Ablation numbers were not hand-verified.
- The fetched text was truncated at 60,000 of 91,363 characters. It cuts off in the Discussion section, so the later content, including limitations and the appendices, was not seen.
Organisations named here
- CWE-78
- CWE-918
- semantic security bugs
Technologies named here
- Atheris
- Bubblewrap
- MCP at First Glance
- MCP-SecLint
- mcp-scanner
- MCPSecBench
- Cisco MCP Scanner
- CodeQL sec-extended suite
- ATR
- VIPER-MCP
- DCIChecker
- Chord
- ToolFuzz
- TitanFuzz, Fuzz4All, AgentFuzz
- MCPXKIT
- FlowGuard, He et al., MCP-Guard
- AEGIS
- MCPCorpus
- Model Context Protocol
- LangGraph
- AutoGen
- CrewAI
- Python
- Repeat-After-Me
Techniques named here
- Semantic security bugs
- Bug classes found
- Semantics-aware sanitizer fuzzing
- Outcome sanitization / outcome oracle
- Path traversal
- SSRF
- Tool poisoning
- Indirect prompt injection
Also named here
- CWE-22
Related in AI Security
