Skip to content

Proposed record: Sandbox boundary taken from a model-supplied value: a tool parameter the model sets defines or widens the sandbox's writable scope #335

Open

Description

@chaksaray

Proposed ave_id: AVE-2026-00089. 00087 is the highest id on develop, and 00088 is claimed by #330 / PR #331.

Mechanism: a coding agent's sandbox computes its writable scope from a value the model supplies in a tool call, such as the working directory of a terminal command, instead of from where the user started the session. A model steered by content it reads (an MCP tool response, a web result, a README) sets that value to a location outside the workspace, and the sandbox grants write access there. The agent can then write files such as the sandbox's own helper binary or the user's shell startup files without approval, and escape the sandbox. The model does not break the boundary; it sets it.

Sources read and what each establishes (each opened and read directly):

  • OpenAI advisory GHSA-w5fx-fh39-j5rw, CVE-2025-59532 ("Sandbox bypass due to bug in path configuration logic"; published 2025-09-19, NVD 2025-09-22; High, CVSS 4.0 8.6; CWE-20 per the Advisory Database; affected Codex CLI 0.2.0 to 0.38.0, fixed 0.39.0; IDE extension fixed 0.4.12): "Codex CLI could treat a model-generated cwd as the sandbox's writable root, including paths outside of the folder where the user started their session." The fix "canonicalizes and validates that the boundary used for sandbox policy is based on where the user started the session, and not the one generated by the model." Credit: "Tzanko Matev (Codetracer)".
  • Fix commit 8595237 ("ensure cwd for conversation and sandbox are separate concerns"). Before it, ExecParams.cwd was passed both as the spawned command's working directory and into sandbox_policy.get_writable_roots_with_cwd(cwd) in seatbelt.rs and landlock.rs. After it, the policy takes sandbox_cwd: &turn_context.cwd (the session's directory) and the model's value only sets command_cwd. A new test, sandbox_distinguishes_command_and_policy_cwds(), checks the split.
  • Cursor advisory GHSA-3p48-7v9f-v5cw, CVE-2026-50548 ("Cursor Desktop sandbox escape via agent-controlled working directory"; published 2026-06-05; Critical; fixed in 3.0): "the sandbox grants write access to the command's working directory. A flaw was identified in how the agent could modify the working_directory parameter, which could cause the sandbox to include writable paths outside the intended workspace." Remediation: "The sandbox no longer grants write access based on an agent-controlled working directory." Credit: "Cato AI Labs".
  • Cato AI Labs, "DuneSlide: Two Critical RCE vulnerabilities via Zero-Click Prompt Injection in Cursor IDE" (Itay Ravia, 2026-07-01; read via the Wayback snapshot of 2026-10-06, since the live page sits behind a bot challenge): "the sandbox constructs its security boundaries based on tool parameters ... when the LLM assigns a non-default value to this parameter, that path is blindly added to the sandbox's allowed write list." The PoC overwrites cursorsandbox, and the post names ~/.zshrc, ~/.zshenv and ~/Library/LaunchAgents as other targets. Timeline: reported February 19; rejected February 23 ("Cursor's threat model does not account for MCP server misuse"); reopened after escalation on February 26; fixed in Cursor 3.0 (April 2); CVEs assigned June 5. Cato scores both findings CVSS 9.8.
  • Pillar Research, "GitPwned: Allowlist to RCE" (Ariel Fogel, 2026-07-20), as corroboration: "the CLI used a model-generated working directory to define its own security boundaries, letting the model specify where it was allowed to write."

Related but different, cited in notes only and kept out of the fingerprint (Gate A):

  • Cursor GHSA-3v8f-48vw-3mjx, CVE-2026-50549 (Critical, fixed 3.0, credit "Cato AI Labs" and "Maor Dokhanian (maordok)"). When canonicalization of a symlink target fails, Cursor "falls back to the original path and writes without approval". The boundary stays fixed at the workspace; a path check against it fails open. That is a path-validation failure, not a boundary the model sets.
  • Anthropic Python SDK GHSA-w828-4qhx-vxx3, CVE-2026-34452 (Medium, CVSS 4.0 5.8, CWE-59 and CWE-367, fixed 0.87.0, credit "hackerone.com/kasthelord"). The memory tool "validated that model-supplied paths resolved inside the sandboxed memory directory, but then returned the unresolved path". It is a validate-then-use race against a fixed boundary, and the advisory's attacker is "a local attacker able to write to the memory directory".

Field-by-field comparison (fingerprint and provenance_vector, plus security_boundary where present):

  • AVE-2026-00053 (path traversal in an MCP file handler): entry_class content. A server's handler fails to canonicalize a caller-supplied path against its own fixed scope. It is an implementation bug, class E in the audit. Here the parameter's value is honored exactly as given, and the policy layer derives the boundary from it.
  • AVE-2026-00054 (JavaScript sandbox escape): entry_class runtime. A payload breaks the language runtime's isolation. Here the isolation works as configured; the configuration came from the model.
  • AVE-2026-00052 (command injection in an MCP handler): an unsanitized parameter reaches a shell. No sandbox policy is involved.
  • AVE-2026-00011 (arbitrary tool invocation via injected directives): entry_class content. It describes injected content directing a tool call with parameters, which is the delivery step of this class. The vulnerability here is the harness's sandbox policy trusting that parameter.
  • AVE-2026-00068 (CLI command composition): working directory appears only as shared shell state between commands. There is no policy construction.
  • AVE-2026-00048 (sub-agent inherits permissions): a delegation scope is left unset. There is no sandbox boundary derived from a parameter.
  • AVE-2026-00088 (sandbox side-effect trust handoff, PR feat: AVE-2026-00088, Sandbox Side-Effect Trust Handoff #331): the boundary stays intact, and a host component later runs files the agent wrote inside it. Here the boundary itself moves.
  • The token-overlap top five (00052, 00053, 00068, 00048, 00022) were read. 00022 (undeclared resource access by instruction) does not share the mechanism either.

Audit answers

  • Capability: a coding agent runs terminal commands inside a sandbox and can choose a command's working directory.
  • Security-relevant behavior: steered by content it reads, the model sets that working directory to a location outside the workspace.
  • Vulnerability condition: the harness builds the sandbox's writable scope from the model-supplied value instead of from the user's session root.
  • Security boundary: user-established session workspace -> sandbox writable scope (the policy) chosen by the party the sandbox constrains.
  • Attacker-controlled input: content the agent reads (indirect prompt injection), which ends up in a tool-call parameter.
  • Missing control: no anchoring of sandbox policy to user-established configuration; tool-call parameters are not treated as untrusted input to the policy layer.
  • Agentic-specific distinction (Q6): replace the LLM with a deterministic program and the flaw, in the form that matters, does not survive. A conventional program does not take its sandbox boundary from the output of the component the sandbox exists to contain. Cato puts it directly: "Traditionally, a remote attacker cannot control the working directory of a sandboxed operation." Strongest counterargument: this is an ordinary input-validation bug (the Advisory Database files it as CWE-20), and a deterministic sandbox that derived its root from an untrusted request would have the same flaw. Answer: the structural error can exist without a model, but the input becomes attacker-reachable only because a model generates it. The constrained party, a model steerable by any content it reads, is the party choosing the boundary. Both fixes confirm the agentic framing: they separate model-supplied execution parameters from user-established policy. Classified A, not E. Model reasoning is in the trigger, unlike the pure implementation bugs discussed in Should AVE catalog pure MCP-implementation bugs with no behavioral component? #234.

Proposed scoring: MEDIUM, aivss_score 6.6. cvss_base 8.6 from the Codex advisory's own vector, CVSS:4.0/AV:N/AC:L/AT:N/PR:L/UI:P/VC:H/VI:H/VA:H/SC:N/SI:N/SA:N, the most conservative vendor reading (Cato scores 9.8 under CVSS 3.1; Cursor rates its instance Critical). AARF sums to 6.0. thm 0.90 (working PoCs and vendor fixes, no known in-the-wild exploitation), mitigation_factor 1 (per-product fixes only, and Cato says further coding agents are being disclosed).

Proposed framework mappings (each read from its primary source):

  • owasp_mcp MCP05 at commit 165fe0f: its checklist names "Agent outputs are not constrained to allowlists of permitted commands, arguments, or file paths" and "No runtime sandboxing isolates tool execution from the host system". MCP02 and MCP07 were read and rejected.
  • owasp_asi ASI05 (2026): it names "sandbox escape". ASI02 was read and rejected by its own scope, since it covers agents operating "within its authorized privileges" and routes code-execution outcomes to ASI05.
  • mitre_atlas AML.T0105 Escape to Host (live ATLAS.yaml v5.6.0). AML.T0053 AI Agent Tool Invocation was considered and left out: it describes the delivery step common to any tool-using record, not the policy flaw.
  • nist_ai_rmf []: NIST AI 100-1 was checked and has nothing more specific than generic security evaluation.

researcher credit: "Cato AI Labs; Tzanko Matev (Codetracer)", with researcher_url set to Cato's DuneSlide post. Cato is credited on CVE-2026-50548 and published the first-party write-up. Tzanko Matev is credited on CVE-2025-59532, the earliest instance, but I found no first-party write-up from him. Not AVE, and not the maintainer.

Activity

  1. added
    ave-recordAdding or modifying an AVE record
    new-classGenuinely new behavioral class, not a variant
    research-sourcedTraced to a citable primary source via research-new-attack-classes
    on Oct 19, 2026
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Labels

    ave-recordAdding or modifying an AVE recordnew-classGenuinely new behavioral class, not a variantresearch-sourcedTraced to a citable primary source via research-new-attack-classes

    Type

    No type

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions