dangerouslyDisableSandbox bypasses sandbox without user approval prompt

Status Fixed / completed
Maintainer reply ✓ Yes — ashwin-ant
Activity 10 comments · opened Mar 14, 2026 · closed Apr 18, 2026
💡 Likely answer: A maintainer (ashwin-ant, collaborator) responded on this thread — see the highlighted reply below.

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

  1. Enable sandbox mode (default)
  2. Have Claude encounter a sandbox restriction (e.g., filesystem write denied, network host blocked)
  3. Claude retries with dangerouslyDisableSandbox: true
  4. 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.

View original on GitHub ↗

10 Comments

github-actions[bot] · 5 months ago

Found 3 possible duplicate issues:

  1. https://github.com/anthropics/claude-code/issues/32300
  2. https://github.com/anthropics/claude-code/issues/14268
  3. https://github.com/anthropics/claude-code/issues/29016

This issue will be automatically closed as a duplicate in 3 days.

  • If your issue is a duplicate, please close it and 👍 the existing issue instead
  • To prevent auto-closure, add a comment or 👎 this comment

🤖 Generated with Claude Code

yurukusa · 5 months ago

The acceptEdits permission mode is the likely cause — it auto-approves all Bash tool calls, including those with dangerouslyDisableSandbox: 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:

#!/bin/bash
INPUT=$(cat)
DISABLE_SANDBOX=$(echo "$INPUT" | jq -r '.tool_input.dangerouslyDisableSandbox // false')

if [ "$DISABLE_SANDBOX" = "true" ]; then
  COMMAND=$(echo "$INPUT" | jq -r '.tool_input.command // empty')
  echo "BLOCKED: Sandbox bypass attempted."
  echo "Command: $COMMAND"
  echo "The model tried to set dangerouslyDisableSandbox: true."
  echo "Review the command and run it manually if appropriate."
  exit 2
fi
exit 0

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 2 is a hard block — the command won't execute.

The broader issue

acceptEdits mode 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.

GMNGeoffrey · 5 months ago

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 dangerouslyDisableSandbox entirely, 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 branch

Unix 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 images

Simple 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 --version

Regex-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, uniq

Permission Flow for Bash Commands

The overall flow for Bash tool calls is something like this:

  1. Auto-allow if sandboxed — if the sandbox is enabled and autoAllowBashIfSandboxed and dangerouslyDisableSandbox is not set
  • check if deny/ask rules with patterns match and route appropriately. Weirdly, this fires for Bash(git log *) in permissions.ask, but not for just Bash. Otherwise, approve.
  1. Check permissions rules — Check deny/ask/allow (in that order) in permissions in settings for an exact match and route appropriately.
  2. Command injection check — Looks for heredoc, ANSCI charaacter hiding, shell metacharacters, etc. Looking for things that would break the normal shell parsing. If suspicious patterns found, returns "ask".
  3. Per-subcommand check — splits command into subcommands (on |, &&, ;, etc). For each:
  • Check deny/ask/allow rules (from settings)
  • validate file paths used in known commands against project and sandbox boundaries
  • Mode-specific checks. The notable one here is that acceptEdits mode approves mkdir, touch, rm, rmdir, mv, cp, sed
  • read only check — if the command is classified as read-only, return "allow"
  1. Combine results — if ALL subcommands return "allow" and no injection detected, the command is auto-approved with no prompt.

The 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:

  1. Document this, including the surprising sandbox interaction and the workaround above
  2. Make it so that the sandbox has its own rules by default and this extra stuff is opt in. Note all the related issues where this behavior is surprising to users and they expect sandboxing to behave differently
manuelmorales · 5 months ago

That was excellent @GMNGeoffrey . Worked perfectly for me. Thanks!

olejorgenb · 5 months ago

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 :)

manuelmorales · 5 months ago

Agree. The app is really buggy,. And bugs get closed unless people like us are constantly keeping them alive.

eproxus · 4 months ago

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).

ashwin-ant collaborator · 4 months ago

This was fixed in v2.1.113 — Setting dangerouslyDisableSandbox on 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.

maayanorner · 4 months ago
This was fixed in v2.1.113 — Setting dangerouslyDisableSandbox on 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):

  Re: #34315 — still reproduces in Claude Code 2.1.114                                                                                                                
                                                                                                                                                                      
  Opus 4.7, Linux. In one session, 5 Bash calls with dangerouslyDisableSandbox: true ran with no approval prompt:                                                     
                                                                                                                                                                      
  1. conda create -n <env> python=3.12 -y                                                                                                                             
  2. pip install -r requirements.txt                                                                                                                                  
  3. git clone --depth 1 https://github.com/google-deepmind/bbeh.git                                                                                                  
  4. python <script>.py --repo-path ./bbeh --dry-run --only <task>                                                                                                    
  5. python <script>.py --repo-path ./bbeh --dry-run --models a,b,c
                                                                                                                                                                      
  System prompt tells the model the bypass "will prompt the user" — it didn't. Likely cause: acceptEdits / Bash auto-approve rules apply to the bypass instead of     
  forcing a separate prompt.                                                                                                                                          
                                                                                                                                                                      
  Expected: every dangerouslyDisableSandbox: true call prompts, regardless of permission mode or Bash allowlist. 
github-actions[bot] · 3 months ago

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.