From aedf6c7964fc040fdf04022d72263ff10a7d2b10 Mon Sep 17 00:00:00 2001 From: win4r Date: Thu, 9 Apr 2026 22:07:10 -0700 Subject: [PATCH] security(approval): close 4 pattern gaps found by source-grounded audit MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Four gaps in DANGEROUS_PATTERNS found by running 10 targeted tests that each mapped to a specific pattern in approval.py and checked whether the documented defense actually held. 1. **Heredoc script injection** — `python3 << 'EOF'` bypasses the existing `-e`/`-c` flag pattern. Adds pattern for interpreter + `<<` covering python{2,3}, perl, ruby, node. 2. **PID expansion self-termination** — `kill -9 $(pgrep hermes)` is opaque to the existing `pkill|killall` + name pattern because command substitution is not expanded at detection time. Adds structural patterns matching `kill` + `$(pgrep` and backtick variants. 3. **Git destructive operations** — `git reset --hard`, `push --force`, `push -f`, `clean -f*`, and `branch -D` were entirely absent. Note: `branch -d` also triggers because IGNORECASE is global — acceptable since -d is still a delete, just a safe one, and the prompt is only a confirmation, not a hard block. 4. **chmod +x then execute** — two-step social engineering where a script containing dangerous commands is first written to disk (not checked by write_file), then made executable and run as `./script`. Pattern catches `chmod +x ... [;&|]+ ./` combos. Does not solve the deeper architectural issue (write_file not checking content) — that is called out in the PR description as a known limitation. Tests: 23 new cases across 4 test classes, all in test_approval.py: - TestHeredocScriptExecution (7 cases, incl. regressions for -c) - TestPgrepKillExpansion (5 cases, incl. safe kill PID negative) - TestGitDestructiveOps (8 cases, incl. safe git status/push negatives) - TestChmodExecuteCombo (3 cases, incl. safe chmod-only negative) Full suite: 146 passed, 0 failed. --- tests/tools/test_approval.py | 169 +++++++++++++++++++++++++++++++++++ tools/approval.py | 20 +++++ 2 files changed, 189 insertions(+) diff --git a/tests/tools/test_approval.py b/tests/tools/test_approval.py index 99edb3b1..675fcf1e 100644 --- a/tests/tools/test_approval.py +++ b/tests/tools/test_approval.py @@ -649,3 +649,172 @@ class TestNormalizationBypass: assert dangerous is False +class TestHeredocScriptExecution: + """Script execution via heredoc bypasses the -e/-c flag patterns. + + `python3 << 'EOF'` feeds arbitrary code through stdin without any + flag that the original patterns check for. See security audit Test 3. + """ + + def test_python3_heredoc_detected(self): + # The heredoc body also contains `rm -rf /` which fires the + # "delete in root path" pattern first (patterns are ordered). + # The heredoc pattern also matches — either detection is correct. + cmd = "python3 << 'EOF'\nimport os; os.system('rm -rf /')\nEOF" + dangerous, _, desc = detect_dangerous_command(cmd) + assert dangerous is True + + def test_python_heredoc_detected(self): + cmd = 'python << "PYEOF"\nprint("pwned")\nPYEOF' + dangerous, _, desc = detect_dangerous_command(cmd) + assert dangerous is True + + def test_perl_heredoc_detected(self): + cmd = "perl <<'END'\nsystem('whoami');\nEND" + dangerous, _, desc = detect_dangerous_command(cmd) + assert dangerous is True + + def test_ruby_heredoc_detected(self): + cmd = "ruby <