Security: Deny rules can be bypassed by flag reordering/insertion
Status Fixed / completed
Maintainer reply None cached
Workaround ✓ Mentioned in thread ↓
Activity 5 comments · opened Jan 16, 2026 · closed Aug 19, 2026
Summary
The permission system's prefix matching for Bash commands can be trivially bypassed by reordering flags or inserting additional flags.
Example
If a user configures:
{
"permissions": {
"deny": ["Bash(rm -rf /:*)"]
}
}
The following commands bypass the deny rule:
rm -fr /(reordered flags)rm -rfi /(additional flag inserted)rm -rfv /(verbose flag added)rm --recursive --force /(long form)
Impact
Users who configure deny rules for dangerous commands may have a false sense of security. The prefix matching is too literal to catch common command variations.
Suggested Fix
Consider one of:
- Semantic parsing - Understand that
-rfand-frare equivalent flag combinations - Regex support - Allow deny rules to use regex patterns like
Bash(rm.*-r.*/:*) - Documentation - Clearly document this limitation and recommend adding multiple variants
Workaround
Users must manually add all common flag permutations:
{
"deny": [
"Bash(rm -rf /:*)",
"Bash(rm -fr /:*)",
"Bash(rm -r /:*)",
"Bash(rm --recursive /:*)"
]
}
This is error-prone and doesn't cover all possible combinations.
Environment
- Claude Code CLI
- macOS / Darwin 23.6.0
Showing cached comments. Read the full discussion on GitHub ↗
4 Comments
Found 1 possible duplicate issue:
This issue will be automatically closed as a duplicate in 3 days.
🤖 Generated with Claude Code
This is closely related to https://github.com/anthropics/claude-code/issues/13371 but doesn't seem to be a duplicate. In this case, even
rm -vrfis enough to bypass something likeDeny(rm -rf)The other reporter claims to have a script that protects against their particular issue, but not sure if it would also resolve this issue
Same class of problem. I wrote a PreToolUse hook in Go that normalizes the command before matching — strips global flags, truncates shell operators, then checks the actual subcommand against deny/ask rules.
Handles flag reordering (
rm -frvsrm -rf) by checking for the presence of flags regardless of position.Source + writeup: https://adriangalilea.com/claude-code-permission-bypass
Good catch. This is a fundamental limitation of string-matching deny rules.
We built an enforcement layer that uses regex patterns instead, which handles flag reordering natively. For example, rm\s+.*-[rR] catches rm -rf, rm -fr, rm -r -f, rm --recursive all in one pattern.
It's open-source: https://github.com/tech-and-ai/claude-rule-enforcer
Layer 1 (regex) blocks in <10ms.
Layer 2 (LLM) handles the grey areas where pattern matching isn't enough. The combination means flag tricks, pipe chains, and alias workarounds all get caught.