[BUG] Permission system treats command chains as single patterns instead of validating individual commands
Bug Description
After the fix for #18605/#16180 (command chaining permission bypass), the permission system now requires the entire chained command to match an allowlist pattern, rather than validating each individual command in the chain as originally intended.
Expected Behavior
According to issue #16180, the permission system should:
- Parse chained commands into individual commands
- Validate each command independently against the permission rules
- Only prompt if ANY command in the chain is not allowed
If all individual commands are in the allowlist, the entire chain should execute without prompting.
Actual Behavior
The permission system treats the entire command chain cmd1 && cmd2 | cmd3 as a single pattern that must match the allowlist. Even when every individual command is explicitly allowed, the chained command still requires permission approval.
Reproduction Steps
- Configure
~/.claude/settings.jsonwith granular bash command allowlist:
{
"permissions": {
"allow": [
"Read",
"Grep",
"Glob",
"Bash: cd",
"Bash: grep",
"Bash: head",
"Bash: git status",
"Bash: git diff"
]
}
}
- Ask Claude to run a command that chains multiple allowed commands:
cd ../dwh && grep -r "new SparkContext" --include="*.scala" | head -10
- Actual result: Permission prompt appears despite
cd,grep, andheadall being in the allowlist
- Expected result: No permission prompt, since all three commands are individually allowed
Impact
This makes granular allowlists effectively unusable for normal development workflows where command chaining and piping are essential shell features. Users are forced to either:
- Allow every possible combination of chained commands (impossible to maintain)
- Use
"Bash: *"wildcard (defeats the security model entirely) - Manually approve every chained command (severely impacts productivity)
Environment
- Claude Code Version: 2.1.x (current)
- Platform: macOS (also affects other platforms)
- API: Anthropic API
Related Issues
- #18605 - Command chaining skips permission checks (CLOSED - the fix for this issue appears to have introduced this regression)
- #16180 - Permission bypass when commands are chained with
&&(CLOSED - states expected behavior) - #15763 - Chained bash commands may bypass individual command permission checks (CLOSED)
- #12871 - Permission rule bypassed when git commit is chained (CLOSED)
Suggested Fix
The permission validation logic should:
- Split chained commands by operators (
&&,||,;,|) - For each command segment, check if it matches any pattern in the allowlist
- Only require user permission if ANY segment fails to match
- Execute the entire chain if all segments are allowed
This preserves the security fix from #18605 while making granular allowlists practical for real-world usage.
This issue has 3 comments on GitHub. Read the full discussion on GitHub ↗