Claude Code Just Closed a Sandbox Side Door. Here's How to Find Yours.
The command stays in the box. The file it writes might not. Here's how to find the side doors in your own setup.
Most people picture an agent sandbox as a wall. The agent's shell commands sit on one side, your machine sits on the other, and nothing crosses.
That picture is missing a door. A command that stays under the sandbox can't run code outside the box, but it can often write a file. And if something outside the box later picks up that file and runs it, the wall didn't matter.
Claude Code just closed one of those doors, and the way it happened says more about agent sandboxes than most security write-ups do.
The one line in the changelog
Claude Code is Anthropic's coding agent for the terminal. Version 2.1.299 reached npm early on October 14 (UTC) as the latest release (npm). Buried in a long list of fixes is this one (changelog):
Fixed a sandboxed shell command being able to write into a
--plugin-dirfolder, whose code Claude Code reloads and runs outside the sandbox
Read that twice, because it describes a two-step escape.
Step one: a shell command running inside the sandbox writes a file. That's allowed. Writing files is most of what a coding agent does.
Step two: Claude Code itself, which is not sandboxed, reloads that folder and runs the code in it with your full permissions.
Neither step looks like an escape on its own. Together they are one.
What --plugin-dir is, and why it mattered
A Claude Code plugin is a folder of add-ons: skills, subagents, hooks (commands that fire at set moments, like after every edit) and MCP servers (small programs that give the agent extra tools) (plugins docs). Normally you install plugins from a marketplace. While you're building one, you can skip that and point Claude Code straight at a folder with the --plugin-dir flag.
The plugin docs are blunt about the trust model: "what the plugin runs, it runs as you." Hooks and MCP servers don't live inside the sandbox. The sandbox docs list "command hooks, local MCP servers, plugin monitors, LSP servers" and helper commands as things that "run with your full access" (sandbox docs).
So a plugin folder is a pickup point. Anything dropped there gets carried outside the wall by a trusted courier. Before 2.1.299, a sandboxed command could drop things there.
The real boundary is a list of folders
Here's the part worth slowing down for.
Claude Code's sandbox already knew about this whole class of problem. Its docs keep a list of "protected paths," files a sandboxed command can't write even inside folders it's otherwise allowed to touch. The reason is spelled out in one sentence: "A command that could edit those files could grant itself permissions, or add a hook or MCP server that Claude Code runs outside the sandbox" (protected paths).
The list includes Claude Code's own .claude settings, skills, agents and hooks, .mcp.json, shell startup files like .bashrc in your working directory, the .vscode folder, and the hooks inside .git (the docs have the full list). You can't exempt any of them with an allowWrite rule.
Every entry on that list follows the same rule: something else runs code from this file later.
Git runs hooks. Your shell runs .bashrc when you open a terminal. VS Code runs tasks from .vscode. Claude Code runs whatever .mcp.json tells it to start. The --plugin-dir bug was simply a folder that belonged on that list and wasn't on it yet.
That's the shift. A sandbox doesn't protect you through the commands it blocks. It protects you through the files it refuses to let those commands write, and that list is only as complete as someone's knowledge of what runs what.
Think of a contractor locked in your garage. They can't get into the house. But you let them leave notes on the fridge, and your house-sitter follows every note without reading it. The lock is fine. The fridge is the problem.
Why this keeps happening
The sandbox lives at the operating system level. It watches each shell command and the processes that command starts (how sandboxing works). It's good at that job.
What it can't see is the future. When a command writes plugin.json or a hook script, the write looks exactly like writing app.ts. The danger shows up minutes later, in a different process, under a different set of rights. The OS has no way to know that one file is a recipe and the other is just code you'll review.
Claude Code's own docs say so in their limitations section. Letting sandboxed commands write to "directories containing executables in $PATH, system configuration directories, or user shell configuration files such as .bashrc or .zshrc can lead to code execution in different security contexts" (limitations). The page opens that section with an honest line: "Sandboxing reduces risk but is not a complete isolation boundary."
So every tool you add that reads config or code from disk is a potential new pickup point. Plugins, mods, task runners, file watchers, a dev server that hot-reloads. Your agent stack grows, and the list of folders that matter grows with it, whether anyone updates the list or not.
Put this into practice
None of this needs special tooling. It needs about fifteen minutes and a willingness to read your own settings.
1. Update and check your version. The fix is in 2.1.299. As of this morning the npm stable tag still points to 2.1.287, so you have to opt in to latest.
npm install -g @anthropic-ai/claude-code@2.1.299
claude --version
Expect 2.1.299. If you installed Claude Code some other way than npm, update through that installer instead. If your team pins stable, raise it with whoever owns that pin, because the fix isn't there yet.
2. Turn the sandbox on if it's off. The sandbox is off by default (docs). Run /sandbox in a session, or add this to ~/.claude/settings.json:
{
"sandbox": {
"enabled": true
}
}
It runs on macOS, Linux and WSL2 (Windows Subsystem for Linux). On native Windows, commands run unsandboxed.
3. Read the "Denied within allowed" list. Run /sandbox and open the Config tab. The docs say it shows the protected paths "resolved for your machine" under Denied within allowed, mixed in with your own denyWrite entries. This is the list of fridge notes your sandbox refuses to let anyone leave. Read it once so you know what's covered.
4. Audit every allowWrite entry with one question. Open your settings and find sandbox.filesystem.allowWrite. For each path, ask: does anything outside the sandbox ever run code from here? The docs' own example grants ~/.kube and /tmp/build, which are fine for most people. Here's what should make you stop:
- Any folder on your
$PATH, such as~/.local/binor~/bin - Shell startup files in your home folder (the protected list only covers the ones in your working directory)
- A folder you also pass to
--plugin-dir - Anything a file watcher, cron job or macOS launch agent (a background job the system starts for you) executes
If a path is on that list, take it out and grant something narrower.
5. Close the retry door. When a command fails in the sandbox, Claude can ask to rerun it unsandboxed using a dangerouslyDisableSandbox flag. In bypassPermissions mode that retry runs with no prompt at all (escape hatch). Strict mode turns it off:
{
"sandbox": {
"enabled": true,
"allowUnsandboxedCommands": false,
"failIfUnavailable": true
}
}
failIfUnavailable makes Claude Code exit at startup instead of silently running unsandboxed when the sandbox can't start (on native Windows, that means it won't start at all, so use WSL2). Strict mode still leaves two gaps: commands you list in excludedCommands, and commands you type yourself at the ! prompt, which run unsandboxed in most sessions. If strict mode breaks a tool you depend on, the softer option is an ask rule for Bash(dangerouslyDisableSandbox:true), which brings back a prompt for every retry.
6. Look at your own scripts with the same eye. This one is my reading, not a line from the docs. Your working directory is writable by design, and it holds files you run later outside any sandbox: package.json scripts, a Makefile, test setup files. A sandboxed command can edit them, and the next time you type npm test in your own terminal, you run its edit. Review diffs to those files the way you'd review a new dependency.
7. For hard isolation, box the whole process. The docs say it directly: to put hooks, MCP servers and the rest behind one boundary, run Claude Code itself inside a container, a VM, or Anthropic's sandbox runtime (scope). A dev container makes the pickup-point problem much smaller, because the courier is inside the wall too.
Honest limitations
This article rests on one changelog line. The changelog doesn't say when the --plugin-dir problem started, who found it, or whether anyone used it. I don't know either, and I'm not going to guess.
The protected-paths list is good, but it's a list. It covers what Claude Code knows runs code. It can't know about the build tool you installed last week or the script your team's onboarding doc tells you to run every morning.
The sandbox also only wraps shell commands. Claude's file tools (Read, Edit, Write), web tools, hooks and MCP servers follow permission rules instead, and some of them run with your full access by design. That's the documented model, not a bug, but it means "sandbox on" doesn't mean "agent contained."
Reads are wide open by default too. A sandboxed command can read most of your machine, including ~/.ssh and ~/.aws/credentials, and it inherits Claude Code's environment variables unless you set up the credential protections (what the sandbox restricts).
The network side has its own caveats. By default the proxy doesn't inspect encrypted traffic, and the docs warn that allowing a broad domain like github.com can open paths for data to leave (limitations).
And none of this is unique to Claude Code. Any agent that sandboxes commands but trusts files on disk has the same shape of problem. Claude Code just happens to document its list in public, which is why we can talk about it at all.
The question to keep asking
You don't need to memorize every protected path. You need one habit.
Whenever you give an agent somewhere new to write, or install something new that reads from disk, ask who picks up files from there, and with what rights. If the answer is "something outside the sandbox, with my full access," that folder is part of your security boundary now, whether you meant it to be or not.
The command stays in the box. Decide what its notes are allowed to say.
Sources: Claude Code CHANGELOG, 2.1.299 entry · @anthropic-ai/claude-code on npm (2.1.299 published 2026-10-14 00:23 UTC; stable at 2.1.287 when checked) · Configure the sandboxed Bash tool · Plugins overview. Docs read October 14, 2026.
Medium metadata
- Title: Claude Code Just Closed a Sandbox Side Door. Here's How to Find Yours.
- Alternate titles: "AI Agent Sandboxes Aren't Command Boundaries Anymore" / "Your AI Agent's Sandbox Has a Side Door. It's a Folder."
- Subtitle options: (1) The command stays in the box. The file it writes might not. Here's how to find the side doors in your own setup. [picked] (2) One changelog line explains how agent sandboxes leak, and the fifteen-minute audit that finds yours. (3) Write here, run there: the escape pattern every coding agent sandbox has to block.
- Description: Claude Code 2.1.299 fixed sandboxed commands writing into plugin folders that run outside the sandbox. Here's the pattern, and how to audit your own setup.
- Tags: (1) Claude Code: the release and docs the piece is built on. (2) AI Agents: the broader audience running coding agents. (3) Cybersecurity: the sandbox-escape pattern. (4) Software Development: the practical audit for working developers. (5) DevOps: settings, containers and isolation choices.
- Article type: B (authority), anchored on a real release. Publish plan: post at 7 to 8 AM, let Medium distribute for 2 to 6 hours, send to subscribers only if it is performing.