trailofbits / trailofbits/claude-code-config
`rm -rf` hook does not catch `find -exec rm -rf` or `xargs rm -rf`
Nobody has claimed this yet.
- Dominant language
- Shell
- Stars
- 2.1k
- Forks
- 161
- Avg merge
- 3d 59m
- Merged PRs (30d)
- 1
Description
The rm -rf PreToolUse hook in settings.json:55 only recognizes rm at the start of the command string or immediately after ;, &&, ||, or |:
(^|;[[:space:]]*|&&[[:space:]]*|[|][|][[:space:]]*|[|][[:space:]]*)rm[[:space:]]
It doesn't catch the two forms an agent produces most naturally when told to clean up a tree:
find . -name '*.tmp' -exec rm -rf {} \;
find . -name '*.tmp' | xargs rm -rf
Neither has rm in a recognized position, so both pass. An rm after a newline in a multi-line command also passes.
README.md:236 frames hooks correctly as "guardrails, not walls," so this isn't a security boundary failing — but -exec and xargs are the first two shapes anyone hits, which makes the guardrail easy to over-trust.
Suggested fix
Either extend the position set to cover -exec and xargs (and a newline), or note the gap in the README so nobody assumes the hook covers indirect invocations.
Related: #48 identifies the same class of gap from the permissions side — deny rules not covering indirect writes. And #33 applied this kind of rigor to this hook already; this is two shapes that pattern didn't reach.
Aside
The permissions.deny entries Bash(rm -rf *) / Bash(rm -fr *) also don't cover rm -r -f, rm -Rf, or rm --recursive --force. Anthropic's docs do warn that argument-matching Bash patterns are inherently fragile, so the hook is the layer that matters — noting it only so the deny list isn't mistaken for coverage.
Found while reviewing the repo against Anthropic's current docs and the installed CLI (2.1.238). One of five separate findings from the same pass.
Contributor guide
No contributing guide indexed for this repository
First steps
- Read the whole issue, then the project's contributing guide.
- Comment on the issue to say you are picking it up — it saves two people doing the same work.
- Fork the repository and make your change on a branch.
- Open a pull request that references the issue number.
Research direction
Open settings.json at line 55 and inspect the existing rm -rf PreToolUse pattern; compare its behavior with the find -exec, xargs, and newline examples in the issue. Check README.md at line 236 for the guardrail framing, then make the chosen coverage or documentation change. Done means the reported indirect forms are either handled or explicitly documented as gaps.
Written by the indexing model from the issue text.
Assessment
- Tech stack
- bash, shell
- Domain
- cli, security
- Issue type
- Bug
- Difficulty
- 2/5
- Estimated time
- 1-3 hours
- Activity status
- Active
- Clarity
- Mostly clear
- Newbie friendliness
- 72/100