Sandbox denyRead is bypassed by allowRead on parent directory and by Bash child processes
Resolved 💬 3 comments Opened Apr 9, 2026 by MasatoShima Closed Apr 9, 2026
Summary
denyRead entries can be bypassed in two ways:
- Parent directory in
allowReadoverrides child path indenyRead: WhenallowReadincludes a parent directory (e.g.,~/.aws) anddenyReadincludes a child path (e.g.,~/.aws/credentials), the allow on the parent takes priority and the deny on the child is ineffective.
- Bash child processes can read denied paths: Even when
denyReadcorrectly blocks theReadtool, a Python subprocess spawned via theBashtool can still read the denied file.
Steps to reproduce
Setup
settings.json sandbox config:
{
"sandbox": {
"enabled": true,
"filesystem": {
"allowRead": [".", "~/.aws"],
"denyRead": ["~/.aws/credentials"]
}
}
}
Test 1: allowRead parent overrides denyRead child
With the above config, ~/.aws/credentials is readable — the denyRead entry is ignored because the parent ~/.aws is in allowRead.
Test 2: Bash child process bypasses denyRead
Run via the Bash tool:
python3 -c "
with open('/Users/<user>/.aws/credentials', 'r') as f:
print(f.readline())
"
This successfully reads the file content, even though ~/.aws/credentials is in denyRead.
Expected behavior
denyReadon a specific path should take priority overallowReadon its parent directory (more specific rule wins).denyReadrestrictions should be enforced on child processes spawned by the Bash tool.
Impact
Users who configure denyRead to protect sensitive files (e.g., ~/.aws/credentials, ~/.ssh/id_rsa) may have a false sense of security. The sandbox does not effectively prevent these files from being read via Bash commands.
Environment
- Claude Code CLI
- macOS (Darwin 23.6.0)
This issue has 3 comments on GitHub. Read the full discussion on GitHub ↗