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
-rf and -fr are 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
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:
-rfand-frare equivalent flag combinationsBash(rm.*-r.*/:*)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