[BUG] Bash deny pattern bypass via ${VAR} curly-brace variable expansion

Resolved 💬 3 comments Opened Feb 7, 2026 by odikia Closed Feb 11, 2026

Bash deny pattern bypass via ${VAR} syntax

Summary

Bash deny patterns using glob matching (e.g., Bash(*__phi*)) fail to match when the command string contains ${VAR} (curly-brace variable expansion). The literal substring is present in the command but the pattern matcher does not match it, causing the command to fall through to user prompt instead of being auto-denied.

Environment

  • Claude Code on WSL2 (Linux 6.6.x)
  • Sandbox enabled, autoAllowBashIfSandboxed: false
  • managed-settings.json with deny patterns

Reproduction

  1. Add this to managed-settings.json deny list:

``json
"Bash(*__phi*)"
``

  1. Test commands:

``
ls $HOME/__phi/ → Auto-denied (correct)
ls ~/__phi/ → Auto-denied (correct)
echo __phi → Auto-denied (correct)
ls ${HOME}/__phi/ → Falls through to user prompt (BUG)
``

  1. The string __phi is literally present in ls ${HOME}/__phi/, yet Bash(*__phi*) does not match.

Expected behavior

Bash(*__phi*) should auto-deny any command containing the substring __phi, regardless of surrounding syntax like ${...}.

Actual behavior

Commands containing ${VAR} appear to break the glob pattern matcher, preventing substring matches from working. The command falls through to the user approval prompt instead of being auto-denied.

Security impact

This bypasses deny patterns intended to protect sensitive directories. If a user clicks "approve" (e.g., not recognizing the path), the sandbox filesystem (read.denyOnly) does not provide a second layer of defense for Bash commands — only the Read/Glob/Grep tools are blocked by read.denyOnly.

Combined, this means:

  1. Deny pattern fails to auto-deny due to ${}
  2. User approves (or has permissive settings)
  3. Sandbox filesystem does not block the Bash read
  4. Sensitive data is exposed

Related issues

  • #23314 — Deny patterns don't match commands with heredoc syntax
  • #18613 — Deny rules bypassed by flag reordering/insertion

All three issues point to the same underlying problem: the glob pattern matcher is too literal and can be bypassed by syntactic variations of the same command.

Suggested fix

The pattern matcher should either:

  • Normalize/escape ${...} before matching, or
  • Use a matching algorithm that treats { and } as literal characters in the command string being tested against deny patterns

View original on GitHub ↗

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