ToFu: Exploiting and Fuzzing the LLM–Orchestrator–Tool Trust Boundary
ToFu is a tool-aware fuzzing framework for LLM tools, including MCP servers. It maps each tool argument, using its metadata, to one of 74 CWE-guided semantics-aware sanitizers (path, URL, SQL and similar). It then generates schema-valid Atheris harnesses and semantic oracles, using runtime tracers for in-process tools and outcome oracles for opaque ones. The LLM (gpt-4.1) only maps sanitizers and writes seeds; it is never the security judge. The paper also shows a "Repeat-After-Me" trick, where an LLM told to repeat attacker-crafted text emits a tool call the orchestrator executes, reproduced on LangGraph, MAF, ADK 2.0, AutoGen, Strands and CrewAI. Across 273 runnable MCP servers (3,405 tools) it reports 253 verified bugs in 343 tools across 118 servers, such as path traversal, log injection and exfiltration. These are failures a crash-based fuzzer would miss. The result matters because it shows LLM-generated tool arguments cannot be treated as trusted.
What it claims
ToFu fuzzes LLM tools (MCP servers) for "semantic security bugs": calls that are schema-valid and return normally but break a property the tool's own description implies, such as a "file within the workspace" path that reads ../../etc/passwd. The headline 253 verified bugs need context. Before manual verification there were 508 candidates across 147 servers. The 253 break down as:
| Class | Bugs |
|---|---|
| Reflected output (CWE-79/116) | 115 |
| Path traversal | 64 |
| Log injection | 58 |
| SSRF | 7 |
| Data exfiltration | 5 |
| OS command injection | 3 |
| Leftover temp file | 1 |
So about two thirds are reflected-output or log-injection findings, which come from always-on checks. For 326 of the 508 candidates, ToFu directly observed the dangerous operation or the unescaped value. The other 182 rest only on "the tool accepted an input the contract says it should reject."
How it works
Of the 74 sanitizers:
- 11 run on every call.
- 35 fire whenever their evidence appears (a tracer event, the output, or runtime state).
- 27 run only when gpt-4.1 selects them.
- 1 is registered but unused.
For each selected outcome sanitizer, the LLM also writes an on_trigger rule. The rule only applies when the flagged call returns without error:
raise_exception: any success is a violation.allow_success_with_fallback: the tool may only return the listed safe values, such as an empty list or null.allow_success_always: the sanitizer is silenced for this tool.
The LLM is called twice per tool (sanitizer selection and seeds) at temperature 0 with a fixed seed. Seeds are adapted from a curated seed bank, and eight file-builder tools generate PDF, DOCX, ZIP and similar inputs. Fuzzing then uses Atheris/libFuzzer coverage guidance with no further LLM calls. Deployment values such as the workspace root come from target config, not metadata.
flowchart TD
T[Schema-valid fuzzed call] --> Q{In-process Python target?}
Q -- yes --> I[21 tracers: open, subprocess, socket...]
I --> IV[Introspection oracle: e.g. canonical path escapes root]
Q -- no / also --> O[Outcome sanitizer flags input]
O --> R{Tool returned success?}
R -- error --> S[Already rejected: no bug]
R -- success --> RULE[Apply on_trigger rule]
IV --> B[Report: invocation, arg, property, evidence]
RULE --> BEvidence
Setup: 273 cleanly executable servers (filtered from MCPCorpus's 13,875 records), 60 s per tool, 12 cores and 32 GB RAM, median 43–46 executions/s.
Baselines. The servers flagged by each analyzer measure different things, and the authors decline to build a leaderboard:
| Analyzer | Servers flagged |
|---|---|
| ToFu | 118 |
| Claude Sonnet-5 audit | 119 |
| CodeQL sec-extended | 95 |
| ToolFuzz | 92 (authors report 46% false discoveries on its correctness failures) |
| VIPER-MCP taint stage | 48 (its agent confirmed 11 exploits) |
| Cisco MCP Scanner | 46 |
Eight servers were flagged by ToFu alone.
Budget. 231 of the 253 bugs appear within 60 s. The remaining 22 surfaced only in 24-hour runs on 34 servers, between 111 s and 70 min in. 73% of tools reach 90% of their final coverage in the first minute.
Ablations (unverified counts):
- Removing both LLM stages keeps about two thirds of the bugs.
- Removing LLM selection makes path traversal, SSRF and command injection nearly vanish.
- An empty seed corpus is the worst arm.
- Enabling all 74 sanitizers doubles the reports with no throughput cost, but over 90% are false on the tools only that arm flags.
- Repeated full runs agree on totals within about 2%, but the bug sets overlap with a Jaccard of only 0.75–0.81.
How to use it
The visible text gives no repo URL, install command or licence. What it does give:
- Runners exist for Python and JS only.
- Runtime tracers work only for in-process Python targets.
- The target must actually run in your environment.
- The authors used a bubblewrap sandbox (read-only root, private
/tmp).
Limits
- Sandboxing is mandatory. During fuzzing, four servers damaged the host.
UltimateCoderMCPdeleted files outside its workspace,obsidian-mcpescaped its vault,tmux-mcpkilled sessions it didn't own, andDesktopCommanderMCPspawned processes without limit. - Reachability gaps. About 63% of servers that only baselines flagged failed to start, hung, or rejected all inputs at credential or schema checks. Example: on
mcp-sitecore-server, 1 of 123 tools ever succeeded. - Static-only issues are invisible. Permissive CORS, bad sanitizing regexes and filesystem races produce no runtime event, so ToFu misses them.
- Code-execution tools are deliberately not flagged. This includes
python_replandapplescript_execute, where VIPER claimed exploits. - Sanitizer selection misses bugs. It missed 13 real bugs. Five were SSRF in a WordPress JS server, where the LLM picked the Python-only tracer instead of the input-side URL sanitizer.
- Manual triage was required to get from 508 candidates to 253 bugs.
- This summary is incomplete. The fetched page was truncated at about 60k of 91k characters, partway through the Discussion. Later limitations, appendices (the sanitizer list) and any release details were not seen.
Organisations named here
- Microsoft
- Amazon Web Services
- CrewAI
- LangChain
- Cisco AI Defense
- GitHub
- OpenAI
- Anthropic
- arXiv
- LangGraph
- Model Context Protocol
Technologies named here
- Python
- ToFu
- GPT-4.1
- Atheris
- LangGraph
- MAF
- ADK 2.0
- AutoGen
- Strands
- CrewAI
- Model Context Protocol
- MCPCorpus
- CodeQL
- MCP at First Glance
- MCP-SecLint
- MCP-Scanner
- Cisco MCP Scanner
- VIPER-MCP
- ToolFuzz
- DCIChecker
- bubblewrap
- ATR
- MCPSecBench
- MCPXKIT
- Node.js
- LLM
Techniques named here
- Repeat-After-Me attack
- Semantic security bugs
- Semantics-aware sanitizers
- Metadata-guided sanitizer mapping
- Runtime introspection
- Outcome sanitization and Outcome Oracle
- Schema-aware harness generation and coverage-guided fuzzing
Related in mcp

OKX Agent Trade Kit (okx-trade-mcp / okx-trade-cli)
