security: close three dangerous-command detection gaps (inspired by Claude Code 2.1.113)#11861
security: close three dangerous-command detection gaps (inspired by Claude Code 2.1.113)#11861teknium1 wants to merge 1 commit into
Conversation
Port three hardening patches from Claude Code 2.1.113's expanded deny
rules to hermes' detect_dangerous_command() pattern list.
1. macOS /private/{etc,var,tmp,home} system paths
/etc, /var, /tmp, /home are symlinks to /private/<name> on macOS.
A write to /private/etc/sudoers works identically to /etc/sudoers
but bypassed the plain /etc/ pattern check. Extracted a shared
_SYSTEM_CONFIG_PATH fragment so /etc/ and the /private/ mirror
stay in sync across redirect / tee / cp / mv / install / sed -i
patterns.
2. killall -9 / -KILL / -SIGKILL / -s KILL / -r <regex>
Parallel to the existing pkill -9 pattern. killall -9 against
non-hermes processes was previously unprotected, and killall -r
can sweep unrelated processes matching a regex.
3. find -execdir rm
Same destructive effect as find -exec rm but ran in each match's
directory. The previous pattern required a literal '-exec ' so
-execdir slipped through.
Guarded by 32 new test cases in 4 test classes:
- TestMacOSPrivateSystemPaths (11 cases)
- TestKillallKillSignals (9 cases)
- TestFindExecdir (4 cases)
- TestEtcPatternsUnaffectedByRefactor (6 regression guards on
the existing /etc/ coverage after the _SYSTEM_CONFIG_PATH refactor)
Inspiration: https://github.com/anthropics/claude-code/releases
(Claude Code 2.1.113, April 17 2026 - "Enhanced deny rules" and
"Dangerous path protection")
|
Review of PR #11861: Security - Close Dangerous Command Detection GapsSummaryThis PR adds critical security test coverage inspired by Claude Code 2.1.113, closing two important gaps in dangerous command detection:
Key Additions1. TestMacOSPrivateSystemPaths (12 new tests)Tests the
2. TestKillallKillSignals (multiple new tests)Extends beyond the existing
Security Impact✅ Prevents bypass attacks: Commands that previously slipped through detection are now caught Code Quality✅ Well-structured test classes with clear documentation RecommendationLGTM - Critical security improvement 🚀 This PR closes important security gaps that could be exploited to modify system configurations or kill arbitrary processes. The tests are well-written, comprehensive, and based on real-world security improvements from Claude Code. No additional changes needed - ready to merge! |
|
Closing in favor of #26829, which salvages this PR onto current main. All three bypasses confirmed reproducible on main before fix; all 12 E2E bypass tests now blocked; all 8 benign-command tests still pass. Conflicts resolved keeping main's |
Summary
Tightens
detect_dangerous_command()against three bash-approval bypasses that Claude Code shipped patches for in v2.1.113 (April 17 2026). All three were confirmed as real gaps on currentmainvia E2E.Gaps closed
/private/{etc,var,tmp,home}pathsecho 'root ALL=NOPASSWD: ALL' > /private/etc/sudoers_SYSTEM_CONFIG_PATHfragment (redirect / tee / cp / mv / install / sed -i)killallwith SIGKILL or regexkillall -KILL firefox,killall -r 'fire.*'\bkillall\s+...patternsfind -execdir rmfind . -execdir rm {} \;-exec(?:dir)?On macOS,
/etc,/var,/tmp,/homeare symlinks to/private/{etc,var,tmp,home}. A write to/private/etc/sudoersworks identically to/etc/sudoersbut bypassed the plain/etc/pattern check.Design
Extracted a shared
_SYSTEM_CONFIG_PATHregex fragment so/etc/and its/private/mirror stay in sync across all 6 patterns that write into system-config paths. Adding another system-protected path in the future is a one-line edit to that fragment.Validation
test_approval.pysuite32 new test cases in 4 test classes guard the fix:
TestMacOSPrivateSystemPaths(11 cases)TestKillallKillSignals(9 cases — includingkillall -l/-Vfalse-positive guards)TestFindExecdir(4 cases — includingfind -execdir lsfalse-positive guard)TestEtcPatternsUnaffectedByRefactor(6 regression guards on the existing/etc/coverage after the_SYSTEM_CONFIG_PATHrefactor)Pre-existing
test_approval_heartbeat.pyfailures confirmed unrelated (reproduce onmainwithout this change — thread-timing flake).Source material
/private/{etc,var,tmp,home}are now treated as dangerous removal targets"Bash(find:*)allow rules no longer auto-approve-execor-deleteflags"Adaptation notes
env rm -rf,sudo rm -rf,setsid rm -rf) were already caught by hermes because\brm\bstill matches mid-command — verified E2E acrossenv,sudo,watch,ionice,setsid,nice,timeout,time,stdbuf. No change needed there./less-permission-promptsslash command in this PR — separate scope.