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:

  1. Parent directory in allowRead overrides child path in denyRead: When allowRead includes a parent directory (e.g., ~/.aws) and denyRead includes a child path (e.g., ~/.aws/credentials), the allow on the parent takes priority and the deny on the child is ineffective.
  1. Bash child processes can read denied paths: Even when denyRead correctly blocks the Read tool, a Python subprocess spawned via the Bash tool 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

  • denyRead on a specific path should take priority over allowRead on its parent directory (more specific rule wins).
  • denyRead restrictions 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)

View original on GitHub ↗

This issue has 3 comments on GitHub. Read the full discussion on GitHub ↗