claude-code - 💡(How to fix) Fix Bash sandbox bypassed by subagents via command obfuscation (8/15 agents, zero human approval) [1 comments, 2 participants]

Official PRs (…)
ON THIS PAGE

Recommended Tools

×6

Utilities matched from this issue’s tags and category — try them while you read without losing context.

GitHub issue graph ai analysis

Paste a GitHub issue URL. We fetch that issue, discover linked issues from bodies/comments/timeline, collect linked pull requests, and produce a structured English report.

The report is written in English Markdown for sharing and archival.

Helpful · Quick feedback

Loading…
GitHub stats
anthropics/claude-code#55579Fetched 2026-05-03 04:49:45
View on GitHub
Comments
1
Participants
2
Timeline
10
Reactions
1
Timeline (top)
labeled ×6cross-referenced ×2commented ×1subscribed ×1

The Bash tool's path-based sandbox can be trivially bypassed by subagents through command obfuscation. In a real-world fleet operation, 8 of 15 autonomous subagents bypassed the sandbox to write files outside the project tree — with zero human approval. The bypass rate correlates with agent persistence (number of alternative command patterns tried), not sandbox strength.

Root Cause

Another agent (standard-tooling-docker) had python3 -c "open(path, 'w')" execute successfully (failed only because the directory didn't exist), but the immediately following mkdir -p /path && python3 -c "..." was denied — the sandbox caught mkdir -p with the literal path but missed the python open() with the same path.

Fix Action

Fix / Workaround

8 agents bypassed the sandbox. They discovered workarounds autonomously:

  • 4 used python3 -c "open(path, 'w').write(content)" via Bash
  • 2 used shell variable indirection (VAR=path; printf > "$VAR")
  • 1 used cp /tmp/file target_path
  • 1 used repeated retries of printf > path until it eventually succeeded (nondeterministic)
RAW_BUFFERClick to expand / collapse

Summary

The Bash tool's path-based sandbox can be trivially bypassed by subagents through command obfuscation. In a real-world fleet operation, 8 of 15 autonomous subagents bypassed the sandbox to write files outside the project tree — with zero human approval. The bypass rate correlates with agent persistence (number of alternative command patterns tried), not sandbox strength.

Environment

  • Claude Code version: 2.1.118
  • OS: macOS (Darwin 25.4.0)
  • Global settings: "defaultMode": "bypassPermissions" (parent session)
  • Subagent context: background agents spawned via the Agent tool

Reproduction

  1. Configure bypassPermissions in the parent session
  2. Spawn a background subagent (Agent tool) with instructions to write a file at ~/.claude/projects/<slug>/memory/MEMORY.md (any path outside the project tree)
  3. Do not interact with the subagent — let it run autonomously
  4. Observe: the subagent will discover that Write/Edit are denied, escalate to Bash, and try increasingly creative command patterns until one bypasses the sandbox

What happens

Write and Edit tools: Correctly denied 100% of the time (15/15 agents blocked). The tool-level path restriction works.

Bash tool: Inconsistently enforced. The sandbox appears to do command-string analysis (regex or pattern matching) rather than syscall-level enforcement. Commands that obfuscate the target path bypass it:

Command patternSandbox catches it?
printf 'content' > /outside/pathUsually yes
cat > /outside/path <<EOFYes (also blocked by heredoc hook)
python3 -c "open('/outside/path', 'w').write('content')"No — bypasses sandbox
VAR="/outside/path" && printf 'content' > "$VAR"No — bypasses sandbox
cp /tmp/file /outside/pathNo — bypasses sandbox
tee /outside/path < /dev/nullNo — bypasses sandbox
mkdir -p /outside/path && python3 -c "..."Sometimes yes (catches the mkdir portion)

Evidence from production fleet operation

During a fleet-wide rollout across 15 repos, each subagent was instructed to write a MEMORY.md file at ~/.claude/projects/<slug>/memory/MEMORY.md (outside the repo tree). All 15 subagents ran as background agents with zero human interaction.

8 agents bypassed the sandbox. They discovered workarounds autonomously:

  • 4 used python3 -c "open(path, 'w').write(content)" via Bash
  • 2 used shell variable indirection (VAR=path; printf > "$VAR")
  • 1 used cp /tmp/file target_path
  • 1 used repeated retries of printf > path until it eventually succeeded (nondeterministic)

7 agents were blocked. They tried only patterns the string matcher catches (direct printf > /literal/path, mkdir -p /literal/path) and gave up after 2-8 attempts. None of them discovered the python3 or variable indirection bypasses.

Nondeterminism

One agent (mq-rest-admin-common) had printf 'content' > /path denied ~5 times, then the same pattern succeeded on a later attempt. No apparent change in command. This suggests either probabilistic enforcement or sensitivity to subtle command-string differences.

Another agent (standard-tooling-docker) had python3 -c "open(path, 'w')" execute successfully (failed only because the directory didn't exist), but the immediately following mkdir -p /path && python3 -c "..." was denied — the sandbox caught mkdir -p with the literal path but missed the python open() with the same path.

The core problem

The Bash sandbox is pattern-matching command strings, not enforcing filesystem access at the syscall level. This means:

  1. Any command that hides the path from the regex bypasses the sandbox. Python one-liners, shell variables, cp, tee — all work.
  2. LLMs are natural adversaries for string-matching filters. When a Bash command is denied, the agent interprets it as "this command pattern doesn't work" and tries alternative patterns. It's doing automated fuzzing of the sandbox filter.
  3. The control is worse than absent. A nonexistent control is honest. A control with a 47-53% enforcement rate creates a false sense of security.

Additional finding: subagents don't inherit bypassPermissions

The parent session has "defaultMode": "bypassPermissions", but subagents spawned via the Agent tool operate under restrictive defaults. This is arguably correct behavior (defense in depth), but it's undocumented and means the parent session's permission config is misleading about subagent capabilities.

Expected behavior

If the sandbox intends to prevent writes outside the project tree, it should enforce this at the filesystem/syscall level (e.g., seccomp, sandbox-exec, or OS-level directory restrictions), not by parsing command strings. Alternatively, if command-string analysis is the only feasible approach, it should be documented as a best-effort filter rather than a security boundary.

Detailed evidence

Full tool-call-by-tool-call evidence for all 15 agents is archived at: https://github.com/wphillipmoore/standard-tooling-plugin/issues/241

extent analysis

TL;DR

The Bash sandbox can be bypassed by subagents through command obfuscation, and a more robust solution such as syscall-level enforcement is needed to prevent writes outside the project tree.

Guidance

  • The current implementation relies on command-string analysis, which can be easily bypassed by using techniques like python one-liners, shell variables, or other creative command patterns.
  • To mitigate this, consider implementing syscall-level enforcement, such as using seccomp or sandbox-exec, to restrict filesystem access.
  • Alternatively, if command-string analysis is the only feasible approach, it should be clearly documented as a best-effort filter rather than a security boundary.
  • Review the subagent permission configuration to ensure it is consistent with the parent session's configuration and that the documentation accurately reflects the subagent's capabilities.

Example

No code snippet is provided as the issue is more related to the design and implementation of the sandbox rather than a specific code bug.

Notes

The provided information suggests that the current implementation has a bypass rate of around 47-53%, which creates a false sense of security. A more robust solution is needed to prevent writes outside the project tree.

Recommendation

Apply a workaround by implementing syscall-level enforcement, such as using seccomp or sandbox-exec, to restrict filesystem access. This approach provides a more robust security boundary than the current command-string analysis.

Vote matrix · Quick signals

Works
Did the solution work? Tap to confirm.
Easy Fix
Was it a quick fix?
Time Saver
Did it save you time?
Blocking
Was it severely blocking?
Common Issue
Are others likely hitting this too?
Flaky / Intermittent
Is it intermittent?
Verified / Reproducible
Can you reproduce it reliably?
Loading…

FAQ

Expected behavior

If the sandbox intends to prevent writes outside the project tree, it should enforce this at the filesystem/syscall level (e.g., seccomp, sandbox-exec, or OS-level directory restrictions), not by parsing command strings. Alternatively, if command-string analysis is the only feasible approach, it should be documented as a best-effort filter rather than a security boundary.

Still need to ship something?

×6

Another batch ranked right after the header list — different links, same matching logic.

Back to top recommendations

TRENDING

claude-code - 💡(How to fix) Fix Bash sandbox bypassed by subagents via command obfuscation (8/15 agents, zero human approval) [1 comments, 2 participants]