dangerouslyDisableSandbox bypasses sandbox without user approval prompt
dangerouslyDisableSandbox bypasses sandbox without user approval prompt
Summary
When Claude sets dangerouslyDisableSandbox: true on a Bash tool call, the sandbox is bypassed without showing a permission prompt to the user. The bypass is silent — the user has no opportunity to approve or deny it.
Steps to Reproduce
- Enable sandbox mode (default)
- Have Claude encounter a sandbox restriction (e.g., filesystem write denied, network host blocked)
- Claude retries with
dangerouslyDisableSandbox: true - Command executes — no permission prompt shown to user
Expected Behaviour
The user should see a permission prompt asking whether to allow the sandbox bypass, with the ability to deny it.
Actual Behaviour
The command executes silently with no prompt. The user has no visibility that the sandbox was bypassed.
Environment
- Claude Code CLI
- Permission mode:
acceptEdits - macOS Darwin 22.6.0
Context
The system prompt instructs Claude that dangerouslyDisableSandbox "will prompt the user for permission." If no prompt is shown, Claude believes it has user consent when it doesn't. This makes the sandbox protection effectively cosmetic — Claude can bypass it at will without the user knowing.
Possibly related to the acceptEdits default permission mode auto-approving bash commands, or to a session-wide auto-approve after the first bypass is accepted.
10 Comments
Found 3 possible duplicate issues:
This issue will be automatically closed as a duplicate in 3 days.
🤖 Generated with Claude Code
The
acceptEditspermission mode is the likely cause — it auto-approves all Bash tool calls, including those withdangerouslyDisableSandbox: true. The sandbox bypass prompt is skipped because the permission mode already said "yes" to everything.Workaround: PreToolUse hook to catch sandbox bypasses
You can add a hook that detects and blocks
dangerouslyDisableSandbox:Register as a PreToolUse:Bash hook in
~/.claude/settings.json.This gives you visibility into every sandbox bypass attempt and blocks them until you can review.
exit 2is a hard block — the command won't execute.The broader issue
acceptEditsmode is designed for convenience but creates a blind spot here. The combination of "auto-approve Bash" + "sandbox bypass doesn't prompt separately" means the sandbox is effectively disabled for the entire session. If you want sandbox protection to be meaningful while still auto-approving normal edits, the hook approach above is currently the only way to get selective enforcement.I am seeing the same issue (v2.1.76) and it is mysterious and confusing behavior. The above comment looks to me like it contains some speculations of a confused Claude about why this is happening. If you want to disable
dangerouslyDisableSandboxentirely, there's a flag for that"allowUnsandboxedCommands": false(https://code.claude.com/docs/en/settings#sandbox-settings), no custom hooks needed. The agent can try to set this flag on its bash tool calls, but they're just ignored. However, allowing the agent to run unsandboxed commands with approval is useful!My Claude also wildly speculated about the cause of this, but I think it's now figured out what's going. I don't think this requires accept edits to be on (I tested and the behavior persists without it), although there is a surprising interaction there. There are other security holes created by accept edits (like Claude editing its own settings file for the sandbox), but those are a separate issue. I tested this after removing all my hooks, configured permissions rules, extra paths, custom sandbox config, etc. to make sure I was seeing the pure tool behavior.
I think the issue here is that there is custom logic baked into the source code that does sophisticated parsing and classifies commands as "read only" and approves them regardless of whether they're bypassing the sandbox.
"Read Only" command classification
Git commands (with per-command flag whitelists):
git diff,git log,git show,git shortlog,git reflog,git stash list,git ls-remote,git status,git blame,git ls-files,git config --get,git remote show,git remote,git merge-base,git rev-parse,git rev-list,git describe,git cat-file,git for-each-ref,git grep,git stash show,git worktree list,git tag,git branchUnix commands (with per-command flag whitelists):
grep,rg,sed,sort,find,file,xargs,ps,netstat,tree,date,hostname,man,info,help,base64,md5sum,sha1sum,sha256sum,npm list,pip list,docker ps,docker imagesSimple commands with args with no shell meta characters (
^cmd(\s|$)[^<>()$\|{}&;\n\r]*$):cat,head,tail,wc,stat,strings,hexdump,od,nl,id,uname,free,df,du,locale,groups,nproc,basename,dirname,realpath,cut,paste,tr,column,tac,rev,fold,expand,unexpand,readlink,diff,true,false,sleep,which,type,node -v,npm -v,python --version,python3 --versionRegex-matched commands (custom patterns):
echo(safe args only),pwd,whoami,history,alias,arch,ip addr,ifconfig,jq(restricted),cd,ls,find(no-exec/-delete),claude -h,claude --help,uniqPermission Flow for Bash Commands
The overall flow for Bash tool calls is something like this:
autoAllowBashIfSandboxedanddangerouslyDisableSandboxis not setBash(git log *)inpermissions.ask, but not for justBash. Otherwise, approve.|,&&,;, etc). For each:acceptEditsmode approves mkdir, touch, rm, rmdir, mv, cp, sedThe readonly check is the main thing causing surprising behavior, I think. User permissions rules applying the same with sandbox bypass commands might also be surprising, but this is actually documented if you look in the sandbox settings configuration window (you might not have since it's the default).
IMO this is something that should be part of the user settings, not a mysterious behavior baked into the source code, but it's understandable why it's not given the complexity required to do this matching. It does seem like it should at least be documented though and my reading of https://code.claude.com/docs/en/permissions does not turn up anything (it talks about Read-Only commands being approved without prompt, but it's strongly implied that it means the Read/Grep/Glob tools and all Bash commands go through the permissions system).
But it seems like a major issue that the same logic applies to sandbox bypass commands. The whole point of doing sandboxing is that this kind of regex/parsing based checking is inherently fragile and famously undecidable in general. That's why instead we place the whole thing in a sandbox and just control the trust boundary. Someone who's doing that is doing so precisely because they don't want this sort of checking.
Workaround
Fortunately, I think there's a relatively simple workaround. When you're running the sandbox, add "Bash" to
permissions.ask. Then at step 3 above all unsandboxed commands give a permissions prompt. The weird behavior where whether or not the rule has a pattern makes a difference saves us here and this doesn't block sandboxed commands.Request
This is wildly-complicated behavior. Anthropic devs please:
That was excellent @GMNGeoffrey . Worked perfectly for me. Thanks!
Do Anthropic even read these issues though? I suspect the reason the issue "balance" looks ok (Open/Closed 6671/28321) is just because they use an aggressive "stale bot"
EDIT: I realize I might appear to be very negative across my issue comments. So to be clear: I do think Claude Code for the most part is a very nice tool :)
Agree. The app is really buggy,. And bugs get closed unless people like us are constantly keeping them alive.
If sandboxing is an official security feature, this should be fixed urgently since it makes the whole feature basically meaningless.
The point is to sandbox things around the agent. Now a compromised or reckless agent can disable its own sandbox and escape it without alerting the user (nothing of this is visible in the output).
This was fixed in v2.1.113 — Setting
dangerouslyDisableSandboxon a Bash command now always prompts for user approval, even in auto mode or bypassPermissions mode. If you're still seeing this in the latest version, please comment with your version and repro and we'll reopen.It still happens (2.1.114). Validated with CC that it is the same bug discussed here (not sure what the repro steps are):
This issue has been automatically locked since it was closed and has not had any activity for 7 days. If you're experiencing a similar issue, please file a new issue and reference this one if it's relevant.