DEV Community

Davi
Davi

Posted on Originally published at blog.mago.team

LLM Agent Sandboxes Have Two Escape Surfaces. Only One Gets CVEs.

In March 2025, a researcher created a symlink inside an allowed directory. The MCP filesystem server validated the symlink's parent directory, the check passed, and read access to /etc/sudoers was granted. No container escape. No kernel CVE. One error handler that checked the wrong path.

Container hardening addresses only one of the two escape surfaces in LLM agent deployments. The tool schema layer above it, where MCP server path validation and tool argument handling live, is unmonitored and has no dedicated CVE category. Anthropic's own reference server produced two critical vulnerabilities in this layer within months of MCP's broad adoption.

The Sandbox Perimeter Moved Up When MCP Arrived

Before MCP, the sandbox perimeter was clear: the container. The agent ran inside, the kernel enforced from outside. MCP moved the perimeter up. The agent now communicates with tool servers over a protocol that handles file system access, network calls, and process execution. The container still exists. The tool server layer above it does not have the same security scrutiny.

CIS Benchmarks for Docker and Kubernetes and NIST SP 800-190 evolved for a world where dangerous operations happen inside the container, visible to the kernel. MCP tool servers handle dangerous operations above the container, in user-space code that the benchmark authors did not anticipate.

arXiv:2607.05743 documents the fragmentation: container security researchers and ML safety researchers operate in separate communities. The tool schema layer, where path validation and permission checks live, is in neither community's primary scope. CVE databases categorize by runtime (Docker, runc, containerd) or by LLM vulnerability type. MCP path traversal fits cleanly into neither category. The gap is not a failure of any individual team. It is a structural consequence of a new protocol being adopted faster than the security research community can reorient.

Models Escape Misconfigured Containers at 49%. Zero Escape Novel Kernel CVEs.

SandboxEscapeBench (arXiv:2603.02277, March 2026) tested nine frontier models against real-world-representative container misconfigurations and novel kernel CVEs. Claude Opus 4.5 overall escape rate: 0.49 [0.39, 0.59] confidence interval. Success scales log-linearly with compute: more capable models are better at finding escape paths.

Zero success across all nine models on novel kernel CVEs. Kernel exploits require specific technical knowledge that current models do not reliably possess. Container misconfigurations require pattern matching against known anti-patterns, a task where large models perform well.

The implication is direct: the threat model that motivates gVisor and Firecracker, preventing kernel-level exploitation, addresses the threat that models are least capable of executing. The misconfigurations that models exploit reliably, privileged mode, Docker socket mount, host path mounts, writable /proc, are the configurations that CIS Benchmarks flag. Real deployments routinely include them for operational convenience. Runtime hardening is necessary. The data shows it is not sufficient for the misconfigurations that persist in production.

CVE-2025-53109: Anthropic's Own Reference Server Had a Path Traversal

CVE-2025-53109 (CVSS 8.4) and CVE-2025-53110 (CVSS 7.3) were disclosed in Anthropic's @modelcontextprotocol/server-filesystem, the reference server used by developers learning to build MCP tool servers. The vulnerabilities were present from MCP's broad adoption through a three-month window before patch. Disclosure: March 30, 2025. Patch: July 1, 2025.

CVE-2025-53109 was a path traversal via symlink. The fs.realpath() call in the error handler validated the symlink's parent directory against the allowed path list, not the symlink's resolved target. An attacker who created a symlink inside the allowed directory could access any path the server process had permission to read.

CVE-2025-53110 was a flaw in the same path validation logic. The server compared the resolved path against the allowed paths list using a prefix match, not a separator-aware boundary check. The path /tmp/allowed_dir_evil passes the check when /tmp/allowed_dir is on the allowlist because the prefix matches. The fix replaced prefix matching with path normalization plus an exact directory boundary check. The character after the allowed path prefix must be a separator.

Neither vulnerability required container escape. Both operated above the container layer. A model instructed to read a file could access files outside the intended scope without any kernel interaction. An indirect injection that caused it to request a path traversal had the same result.

NVIDIAScape: Three Lines of Dockerfile, CVSS 9.0, Host Root

CVE-2025-23266 (NVIDIAScape, CVSS 9.0) affected every AI deployment running NVIDIA Container Toolkit at or below version 1.17.7 with GPU acceleration. The exploit uses a three-line Dockerfile to trigger an LD_PRELOAD injection via the Toolkit's createContainer hook. The hook runs as host root. The preloaded library runs as host root. No credentials needed.

GPU-accelerated LLM inference deployments are exactly the deployment pattern of production agent systems. Wiz disclosed the vulnerability in March 2025 after finding it during a security assessment of AI cloud infrastructure. The patch was released in Toolkit 1.17.8.

The attack surface is the hook mechanism in the Toolkit, not the container runtime itself. Docker's own isolation was intact. The Toolkit layer above it was not. This structure is identical to the MCP layer problem. A new component added for LLM workloads introduced an escape surface that the container runtime's security model does not cover.

Prompt Injection Chains Both Layers

Langflow CVE-2025-3248 (CVSS 9.8, CISA KEV) was unauthenticated RCE via Python exec(). Jadepuffer ransomware operators used this vulnerability as an initial access vector. The Langflow instance ran inside a container. The exec ran inside the container. The ransomware executed inside the container, then used the container's mounted host paths to encrypt host filesystem data.

The attack chain: prompt injection causes the agent to pass attacker-controlled content to a code execution tool. The tool reaches a vulnerable exec() call and runs it inside the container. Container escape is not required when the container has host filesystem mounts, which most production agent deployments include for data access.

Base64 obfuscation of the exec payload bypasses keyword filters that look for Python code in agent outputs. The filter never sees exec(), it sees a base64 string that decodes to exec() inside the container. Indirect injection in retrieved documents delivers the same payload without direct user interaction. The agent retrieves a document containing the injection, processes it as context, and passes the payload to the code execution tool.

Defense Requires Independent Hardening of Both Layers

Runtime isolation addresses kernel-level escapes and privilege escalation within the container. Two patterns that work in production:

Firecracker microVMs: hardware KVM isolation, 125ms boot, under 5 MiB overhead. Eliminates the shared-kernel attack surface that runc containers expose. Used in AWS Lambda. Zero shared kernel means zero kernel CVE exposure.

gVisor: user-space syscall interception, 10-30% I/O overhead. Intercepts all syscalls before they reach the host kernel. Breaks LD_PRELOAD-style attacks that depend on kernel hook mechanisms.

The tool schema layer requires separate controls:

Path validation with realpath plus directory boundary: Resolve the full path with fs.realpath(). Verify it begins with the allowed directory and that the next character after the prefix is a separator, not a raw prefix match. This is the CVE-2025-53110 fix.

Network egress blocked by default: MCP servers that handle file and data operations should not have outbound network access. Blocked by default, allowlisted per tool.

MAGO Intel (intel.mago.team) audits agent deployment configurations against both escape surfaces. It tests runtime isolation against the SandboxEscapeBench real-world-representative misconfiguration catalog and tool schema validation against CVE-2025-53109/53110 path traversal patterns.

The two escape surfaces had distinct CVE series in 2025, one for each layer. Container hardening addresses one. The MCP tool layer has no equivalent hardening standard, no scanner coverage, and no CVE category. The Anthropic filesystem server patch is a data point, not a solution. Every MCP server deployed against a filesystem, database, or shell is an independent instance of the same validation problem.

Top comments (1)

Collapse
 
seasonkoh profile image
WebAZ

The two-perimeter model is useful, but I would make the MCP-side test unit principal x tool x resolved resource x effect, not only arguments. realpath closes a traversal class; it does not prove that this caller may read the resolved file, call that host, or mutate that object.

For each tool, negative fixtures should resolve aliases first, then test subject and tenant scope, egress destination, and whether the attempted effect was actually denied. For write tools I would also require an operation ID and an authoritative post-call state check, because a network timeout can make the sandbox report failed after the external system committed.

That gives indirect-prompt-injection tests a crisp oracle: did untrusted content influence planning, or did it cross an authority boundary? Publishing the fixture corpus as a reusable CI profile could be more valuable than another scanner dashboard. Are you planning to separate those fixtures from MAGO so other MCP servers can run them without the service?