Skip to content

fix: allow rm -rf on nested paths while still blocking top-level and wildcard wipes - #21

Merged
chouzz merged 1 commit into
mainfrom
fix/rm-rf-nested-path-false-positive
Sep 14, 2026
Merged

chouzz merged 1 commit into
mainfrom
fix/rm-rf-nested-path-false-positive

Conversation

@chouzz

@chouzz chouzz commented Sep 14, 2026

Copy link
Copy Markdown
Owner

Problem

Follow-up to #19 (and the #17/#18 hardening): the fallback rule added in #18

(r'\brm\s+.*-.*rf\s+/\S+(?:/|(?:\s|$))', 'Remove arbitrary absolute path')

blocks every absolute-path rm -rf, including ordinary nested paths:

rm -rf /root/otherdirectory   # BLOCKED ❌
rm -rf /tmp/build             # BLOCKED ❌
rm -rf /home/user/project     # BLOCKED ❌

These are this tool's bread-and-butter operations — an SSH agent that can't clean a build directory isn't usable. Worse, the block is trivially bypassed (cd /root && rm -rf otherdirectory passes), so the rule adds friction without adding safety. There is also a second, subtler instance: the keyword-layer pattern \brm\s+-rf\s+/root\b matches /root/child because \b holds between t and /.

Fix

Rework the rm -rf hardening to be depth-aware:

Blocked (any argument position, optional trailing slash):

  • Top-level absolute paths: rm -rf /, /home, /etc/, rm -rf /home /tmp, rm -rf /root/ /etc/
  • Wildcard wipes: rm -rf /home/*, rm -rf /*, rm -rf *
  • Critical system files: /etc/shadow, /etc/passwd, /etc/sudoers, /etc/group, /etc/gshadow, /etc/fstab, /boot/*
  • Parent traversal: rm -rf .. (unchanged)

Allowed (depth ≥ 2 — specific content, this tool's normal use case):

  • rm -rf /root/otherdirectory, /tmp/build, /home/user/project, /var/log/app/, /opt/mytool/cache, /etc/nginx, /usr/share/doc, ./build

Regression gate: all issue #17 payloads (rm -rf /home, /home/*, /etc/passwd, /home ; echo PWNED, cat /etc/shadow, cp /etc/shadow /home/leak, tar czf ... /etc/shadow) remain blocked — verified in tests.

Tests

Extended both block/allow lists (now 15 blocked + 13 allowed cases covering multi-argument commands, trailing slashes, wildcards, critical files). Full suite: 12 passed.

…wildcard wipes

#18's fallback 'Remove arbitrary absolute path' rule blocked EVERY
absolute-path rm -rf, including /root/myapp/build or /tmp/build —
this tool's normal daily use. Worse, it trained callers to bypass the
validator entirely via 'cd /root && rm -rf subdir'.

Rework the hardening rules:
- block rm -rf targeting any TOP-LEVEL absolute path (any argument,
  optional trailing slash): rm -rf /, /home, /etc/, multi-arg variants
- block wildcard wipes (rm -rf /home/*, /*) and critical system files
  (/etc/shadow, /etc/passwd, /etc/sudoers, /etc/fstab, /etc/group,
  /etc/gshadow, /boot/*)
- ALLOW nested paths (depth >= 2): rm -rf /root/otherdirectory,
  /tmp/build, /home/user/project, /etc/nginx

Also fix the keyword-layer 'rm -rf /root\b' pattern whose word boundary
between 't' and '/' made it match /root/child too.

All issue #17 payloads remain blocked (verified in tests).
@chouzz
chouzz merged commit a5b59b8 into main Sep 14, 2026
2 checks passed
@chouzz
chouzz deleted the fix/rm-rf-nested-path-false-positive branch September 14, 2026 12:44
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant