Skip to content

v1.30.3

Choose a tag to compare

@pchalasani pchalasani released this 28 Oct 11:50
· 10 commits to main since this release

Safety hooks: rm detection survives wrappers and attached option values

This release closes a class of bypasses in the rm block hook, where a
deletion could be hidden from the guard by the way it was spelled rather than
by what it did.

What changed

The hook previously looked at the first word of each command, so anything that
ran rm on your behalf slipped past it. Wrapper options are now parsed left
to right, per wrapper, and the hook inspects the executable that actually gets
run:

  • Attached option values no longer swallow the command. sudo -uroot rm victim and xargs -In rm victim were read as if rm were an option
    operand; they are now correctly identified as deletions. Each wrapper carries
    its own value-taking option list, because -n takes a value for nice and
    xargs but is a flag for sudo.
  • find and fd actions are followed. The hook reads the command after
    -exec, -execdir, -ok, -okdir, -x, --exec, -X and
    --exec-batch, treats find … -delete as deletion, and recurses through
    wrappers in those commands — so find . -exec env rm {} + and
    fd -x sudo rm are blocked.
  • Literal redirections no longer hide the wrapped command, e.g.
    a redirection attached directly to the rm command word.
  • Quoted operands are preserved, and doas / sudo command modes and
    argv0 values are handled.
  • Literal env -S is parsed on its own terms, including its quote,
    separator and escape rules — backslash-underscore separators and
    backslash-c truncation among them.
  • Lookup and policy modes stay non-executing, so command -v rm,
    command -V rm, echo rm, git rm --cached, find . -name '*.rm' and
    sudo -u rm ls remain allowed.

Credit

Thanks to @fizz (Fizz Orange) for finding the first-word-only limitation
and doing the original wrapper/find/fd work in #245. Those commits are
carried over here with authorship intact; #249 adds counter-verified repairs on
top. #245 is closed as superseded.

Verification

607 tests pass in the safety-hooks hook suite (222 subtests), including 295
new lines of wrapper cases in test_rm_wrappers.py. The added tests were
counter-verified to fail against the unfixed sources, and real xargs, env
and find executions confirm the command interpretation.

Known limitations (disclosed, not fixed here)

  • The shared command extractor still splits escaped find -exec semicolons and
    compound redirections at shell operators, which can lose later context.
    Fixing that shared shell parsing is deferred from this patch.
  • The env -S parser handles literal strings; runtime environment-variable
    interpolation is not evaluated.
  • This is not a complete Bash grammar or execution analysis.

PRs in this release

  • #249 — fix(safety-hooks): preserve rm detection through wrappers and option
    operands (supersedes #245 by @fizz)

Full changelog: voxtype-v0.3.10...v1.30.3