
MCP Sandbox Escape: CodeCall Host RCE via a Leaked Zod Schema (CVE-2026-67531)
CVE-2026-67531: a FrontMCP CodeCall sandbox bug let one tools/call reach host RCE often with public auth. What to patch, and how APRF Core maps it.
MCP CodeCall sandbox escapes are Tool Safety and AI Security first exec-tool gates, host-boundary controls, and MCP machine identity plus Supply Chain pins for the plugin that claimed containment. Part of APRF Incident Analysis.
AI Production Readiness Framework
Related APRF controls
In plain language
Think of an AI assistant that is allowed to run small programs in a locked room so it can help with work—without touching the rest of the company’s computers. In this incident, that “locked room” had a hidden defect: when the assistant asked for a simple description of another tool, the system accidentally handed over a master key to the whole building. With one request, and often without even logging in, someone (or a tricked AI) could read passwords sitting on that server, write files, and act as if they were the server itself. The vendor has issued a fix; teams should update, and treat “sandboxed code next to AI tools” as something that can still hurt the business if the lock fails.
The Incident
An MCP server is running with a “secure” script tool. The docs promise a zero-trust runtime. The AST guard blocks `.constructor`. Someone or something sends one `tools/call`:
`codecall:execute` with a short script.
No login header. No shell planted on disk beforehand. The script asks the sandbox for a tool’s schema, walks a property the membrane is forced to return raw, and reaches the host `Function` constructor. Moments later the server process has written a proof file on the host filesystem, listed environment names that look like tokens, and run `id` as the server user.
Nothing magical about the model. The escape is a JavaScript trust-boundary bug inside a capability that exists specifically so agents can execute code near tools.
Here is the mechanism in engineering terms—and why “we have a sandbox” was not enough.
Why existing thinking failed
The comfort story was layered and sincere:
- We have a sandbox / enclave / bank-grade runtime.
- The AST guard refuses `.constructor` and `__proto__`.
- Schemas are just metadata—safe to introspect.
- Default public mode is fine until we turn auth on.
That story fails when live host objects cross the membrane. A Proxy that blocks `constructor` still has to obey ECMAScript invariants: if a property is non-configurable and non-writable, the trap cannot invent a different value. Zod v4 installs `_zod` that way. Hand a live Zod instance to the guest, and containment ends at the next hop—even while the bridged closures (`getTool.constructor`, …) still look sealed.
Lexical denylists and runtime membranes were supposed to back each other up. The denylist never saw a key built with `["c","o","n","s","t","r","u","c","t","o","r"].join("")`. The membrane never got a chance once `_zod` was raw.
Research proves it
Confirmed in GHSA-mp29-fxh8-92px (2026-07-26) and CVE-2026-67531 (record updated 2026-08-05):
- `@frontmcp/plugin-codecall` ≤ 1.5.6; fixed in 1.5.7.
- `getTool()` returned live Zod (`rawInputSchema` / `outputSchema`) into the enclave (`allowFunctionsInGlobals: true`).
- Escape → RCE as the server user (CWE-94 / CWE-501): env secrets, OAuth/JWT, DB creds, cloud metadata, host FS.
- One MCP `tools/call`. Default `auth: { mode: 'public' }` → unauthenticated callers; with auth, indirect prompt injection can still trigger it.
- Reproduced on published `1.5.6` and the repo’s `demo-e2e-codecall` server (default `secure` preset—not a weakened lab). Negative control: inert JSON Schema via `getInputJsonSchema()` / `getOutputJsonSchema()` (fix commit `209cddd1`).
Reported: CVSS 9.3; credit `@fg0x0`. Unknown: how many internet-facing deployments were exposed pre-patch.
Engineering takeaway
If your agent stack can execute code next to tools, treat the sandbox as a hostile guest that must receive only structured-cloneable data, never live host graphs. Pair that with AUTHN-M2 on the MCP edge and TOL-M3 gates on exec-class tools.
Why this matters
If an MCP script tool can reach the host process, secrets and lateral movement stop being theoretical, they become one `tools/call` away. That hits platform engineers running MCP frameworks with script/CodeCall plugins, agent-host owners who bind “helpful” execute tools, AppSec reviewing “sandboxed” tool runtimes, and anyone who copied a getting-started server with public auth into a reachable environment.
What class of systems: Agents + MCP + Tools + Sandbox. Pure RAG without code execution is less directly hit—unless retrieval tools feed content that later drives an execute tool (indirect injection path in the advisory).
Can a startup ignore it? No if you ship CodeCall (or any host-side script tool) on an MCP server. Maybe if you have zero code-execution tools—and even then, inventory quarterly so a plugin does not land “temporarily” in prod.
This is a different lesson from “bind fewer tools.” Here the dangerous tool was the sandbox itself.
Timeline
| Phase | Date / window | Notes | Fact class |
|---|---|---|---|
| Discovery | ≤ 2026-07-25 (PoC timestamps in advisory) | Reporter reproduces escape on e2e CodeCall server; positive / baseline / negative controls | Confirmed (advisory) |
| Disclosure | 2026-07-26 | GHSA-mp29-fxh8-92px published (Critical) | Confirmed |
| CVE / catalog | 2026-08-05 (CVE record update) | CVE-2026-67531 listed; CNA GitHub | Confirmed |
| Patch | 1.5.7 / commit `209cddd1` (+ release line) | Stop handing live schemas into the enclave; plain JSON / sandbox-safe projection | Confirmed |
| Mitigation | Now | Upgrade ≥1.5.7; disable CodeCall if unused; require auth; rotate secrets if exposure possible; pin plugin versions | Confirmed guidance + org-specific rotation |
Root Cause
Two bugs composed into one escape:
1. Trust-boundary violation: live host Zod instances entered the guest realm as “metadata.”
2. Membrane vs language invariant: non-configurable `_zod` forced the Proxy to return the raw host object; host `Function` followed.
A third deployment property made it cheap: default public auth so `codecall:execute` was a network-reachable capability without credentials. Auth does not remove the bug—it only changes who (or which injected model turn) can call it.
The failure class is mcp-sandbox-escape: containment claimed at the script layer, broken by object graph smuggling—not prompt wording, and not “MCP is insecure” as a slogan.
APRF Lens
Under APRF 0.11.0 Core (agents lens for this week’s assessment), the story sits in Tool Safety and AI Security, with Authentication, Supply Chain, and Observability in support:
- TOL-M1 / TOL-M2 / TOL-M3 — independent authz; allowlists; extra gates for exec / irreversible tools (`codecall:execute` is the archetype)
- AUTHN-M2 — production MCP must not be anonymous / shared-static-key by default
- SEC-M1 — untrusted input (including model-shaped tool args / script bodies) must not authorize privileged side effects without server-side policy
- SEC-M4 — model/tool runtime must not become a universal proxy into the host/process interior
- SCI-M2 — pin and review MCP plugins (`@frontmcp/plugin-codecall` versions matter)
- OBS-M1 — request → model → tool → outcome traces so one-shot `tools/call` escapes are reconstructable
Standing caveat: APRF assessments can miss evidence. A repository is not the only source of truth. Runtime auth mode, internet exposure, secrets in process env, vendor consoles, CI variables, production prompts, and the deployed plugin version often never appear in git. Absence of a finding is not proof of readiness.
APRF mapping confidence: High — the advisory’s mechanism and default-auth fact pattern align tightly with these Checks. Abuse path confidence: High — PoC + curl reproduction documented by the advisory.
Abuse Path Analysis
- Caller → Execute — public default auth (`AUTHN-M2` gap) or authorized/injected caller still reaches exec.
- Execute → Guest → live Zod — metadata smuggling; SEC-M4 / TOL-M1 posture fails when the “tool” is host RCE.
- Raw → Host Function → process — membrane defeat; TOL-M3 should have required a stronger gate than “sandboxed script.”
- Process → secrets / FS / cloud — blast radius of shared agent hosts (SEC2 family operationally; rotate if exposed).
- 1.5.7 / disable plugin / AUTHN-M2 — edges that cut or raise cost of the path.
Abuse path confidence: High — primary-source PoC. Speculative only: your estate’s exposure count.
Standing caveat (brief): this graph does not see your load balancer, secret store, or whether CodeCall is enabled in prod. APRF can miss those without runtime evidence.
Relevant Controls
| APRF Check | Category | Why it applies | Evidence you’d expect |
|---|---|---|---|
| TOL-M1 | Tool Safety | `tools/call` must not become host RCE without independent authz | Gateway/runtime authz covering 100% of tool paths; deny suite |
| TOL-M2 | Tool Safety | Agents should not invent/reach exec tools outside allowlist | Per-agent allowlist; unknown-tool deny tests |
| TOL-M3 | Tool Safety | Code-execution tools need gates beyond base allowlist | Impact inventory; approval/dual-control or hard disable |
| AUTHN-M2 | Authentication | Default public MCP is incompatible with production | Connection inventory; 0 anonymous prod MCP |
| SEC-M1 | AI Security | Script body / tool args are untrusted input | Server-side policy; injection/privilege corpus with measured deny |
| SEC-M4 | AI Security | Tool runtime must not proxy the whole host interior | Boundary tests; no live host object graphs in guest |
| SCI-M2 | Supply Chain | Pin `@frontmcp/plugin-codecall` (≥1.5.7); review plugins | Inventory with pins/owners; no floating latest |
| OBS-M1 | Observability | Reconstruct the single `tools/call` that escaped | Traces: caller → tool → outcome; retain where policy allows |
Assessment evidence from FrontMCP (public framework repo @ v1.5.6)
What we ran: APRF Auditor CLI against agentfront/frontmcp @ `v1.5.6` / `744897ad…` (vulnerable line). Profile: Core + Agents. Offline (no `--base-url`).
This is a public framework monorepo (demos/e2e included)—not a named breach victim. We are not publishing a “FrontMCP failed APRF” scorecard. Fair question only: what would an assessment surface that protects production hosts using CodeCall-class tools?
Assessment evidence (failure-class slice):
- AUTHN-M2 — Not Demonstrated offline (no MCP/S2S inventory / live probe). Advisory separately Confirms default public auth—the anti-pattern AUTHN-M2 blocks.
- TOL-M3 — Not Demonstrated for exec/high-impact gates; `codecall:execute` is the archetype.
- TOL-M1 / TOL-M2 / SCI-M2 / SEC-M1 / OBS-M1 — Partial: signals without measured production inventories/gates—evidence incomplete for a production-host PASS. Pin to ≥1.5.7 remains mandatory ops work.
Protect a production host: upgrade or remove CodeCall; no public auth on reachable MCP; TOL-M3 on exec; inert data only across membranes; rotate secrets if pre-patch exposure possible.
Limits: no live re-exploit here; no customer estate scan; demo/fixture paths can confuse secrets collectors. Auditor confidence: Medium. Advisory remains the source of truth for the escape. Runtime DNS/WAF/secret-manager state can still be invisible to any repo assessment.
How to Prevent It
Immediate (24–72h)
- Upgrade `@frontmcp/plugin-codecall` (and SDK line) to ≥ 1.5.7; redeploy.
- If you cannot upgrade immediately: disable/remove CodeCall / `codecall:execute`.
- Turn off public auth on any reachable MCP; bind localhost or require machine identity.
- If exposure possible: rotate OAuth client secrets, JWT secrets, session keys, DB creds, cloud keys present in that process.
- Inventory where CodeCall (or equivalent script tools) is enabled.
30 days
- TOL-M3 policy: exec/eval tools off by default; dual control when required.
- Boundary tests: guest may receive only structured-cloned / frozen plain data (regress the Zod/`_zod` class of bugs).
- AUTHN-M2 inventory for every prod MCP; deny anonymous.
- SCI-M2: pin plugin versions; alert on floating tags.
- OBS-M1: alert on `codecall:execute` / script-tool spans and on authz denies.
Longer term
- Runtime enforcement of dangerous property access (not only AST lexical rules).
- Treat MCP frameworks like privileged application servers in your SDLC (SEC-M3 abuse suites that include sandbox escape cases).
- Contract tests that fail CI if a plugin reintroduces live host objects into guest globals.
Engineering Lessons
1. Sandboxes fail at object graphs, not slogans—never pass live host instances to guests.
2. Lexical guards ≠ runtime containment—computed property names will walk around AST denylists.
3. Default public MCP is a production incident waiting for a tool—AUTHN-M2 before exposure.
4. Exec tools are TOL-M3 by definition—a membrane is not an approval gate.
5. Pin the plugin that claims “bank-grade”—SCI-M2 would have made 1.5.6 → 1.5.7 a forced move.
Could this happen to you?
You should read this if…
- ✓ You use MCP
- ✓ You have agents
- ✓ You expose tools to models
- ✓ You ship sandboxed script / CodeCall / eval tools beside those tools
- ✓ Your MCP defaulted to public or shared auth
- ✓ Secrets live in the same process env as the MCP server
If two or more apply, treat the Relevant Controls table as a gate checklist this week.
Continues in the APRF Incident Corpus
Related in this series:
- MCP tool allowlists / confused deputy — open catalogs without platform disposal
- OpenAI / Hugging Face sandbox-escape — eval/containment agency theme; different mechanism
Map these Checks with the APRF self-attest (questionnaire only—not certification), or run the open APRF Auditor skill against your agent host for artifact-backed findings.
FAQ
Would assessing FrontMCP’s public repo have “caught” CVE-2026-67531 like a CVE scanner? Not as a CVE ID. A Core run at v1.5.6 still surfaces incomplete AUTHN-M2 / TOL-M3 evidence—why the bug was cheap to reach. The advisory proves the membrane break. Assess your host and plugin pins.
Same as the MCP tool-allowlist / confused-deputy analysis? No—that was open tool catalogs; this is host-object smuggling inside an exec sandbox. Both can coexist.
What can APRF miss outside the repo? Live auth mode, whether CodeCall is enabled, secret rotation, metadata egress. Repo outcomes ≠ production readiness.
Does authentication alone fix it? Confirmed: no—it changes who can call it. Patch or disable CodeCall; auth is defense in depth.
Trust “secure VM” marketing? Trust boundary tests and patch currency. Demand inert data across the membrane.
References
1. GHSA-mp29-fxh8-92px — CodeCall sandbox escape to host RCE via live Zod schema exposed by getTool, FrontMCP / GitHub Advisory (2026-07-26).
2. CVE-2026-67531, CVE Record (updated 2026-08-05).
3. FrontMCP v1.5.7 release — fixes GHSA-mp29-fxh8-92px (and GHSA-h8wf-g76c-wjwg path traversal).
4. Patch commit `209cddd1`.
5. APRF 0.11.0 Check catalog — TOL-M1–M3, AUTHN-M2, SEC-M1, SEC-M4, SCI-M2, OBS-M1 (/aprf/spec/).
Need hands-on help? Book a free 30-minute production audit.
Book Free 30-Min Production AuditNext: Tool Safety
Open the related pillar specification for mandatory checks, artifacts, and pass conditions. Self-attest is optional.