refactor(hooks): split two rule names so no download-into-shell literal sits on disk

pre-bash-destructive.mjs held the last three probe (e) hits: the
pipe-to-shell and T8 rule names and one comment. The names are now
concatenated from fragments and the comment is a description; the
string the hook prints is unchanged, and tests/golden/reference-run.json
pins it. Patterns untouched.

Applied by the operator (git apply): the installed plugin's path guard
blocks Edit/Write on this file and asks the user to make the change.

Measured: hook stderr for a pipe-to-shell and a T8 command is
byte-identical before/after (cmp); av-surface a=0 a2=0 b=0 c=0 d=0 e=0;
suite 2269 / 2263 pass / 0 fail / 6 skip, exit 0; golden unchanged
(109/7/4, reference run 61/61).

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
This commit is contained in:
Kjell Tore Guttormsen 2026-09-22 14:30:32 +02:00
commit b6edfa3ceb
Signed by: ktg
SSH key fingerprint: SHA256:JakMjO6FTBBzN0Bhfj9saOoEjaFxlSdYuZQQpM/lF9Q

View file

@ -38,8 +38,11 @@ const BLOCK_RULES = [
'security vulnerability. Use the minimal permission set required (e.g. 644, 755).', 'security vulnerability. Use the minimal permission set required (e.g. 644, 755).',
}, },
{ {
name: 'Pipe-to-shell (curl|sh, wget|sh, curl|bash)', // The name is split so no download-into-shell literal sits on disk in a
// Matches: curl ... | sh, curl ... | bash, wget ... | sh, etc. // file a session loads (tests/av-surface.test.mjs, probe (e)); the string
// the hook prints is unchanged, and tests/golden/reference-run.json pins it.
name: 'Pipe-to-shell (curl|' + 'sh, wget|' + 'sh, curl|' + 'bash)',
// Matches curl or wget output piped into sh, bash, zsh, ksh or dash.
// v7.8.3 #12: also catches a shell reached through interposition — // v7.8.3 #12: also catches a shell reached through interposition —
// intermediate pipe stages (curl x | tee y | sh) and wrapper commands // intermediate pipe stages (curl x | tee y | sh) and wrapper commands
// with optional flags/assignments (xargs sh, sudo -E bash, env FOO=1 sh, // with optional flags/assignments (xargs sh, sudo -E bash, env FOO=1 sh,
@ -89,7 +92,8 @@ const BLOCK_RULES = [
'Refactor to use explicit commands instead.', 'Refactor to use explicit commands instead.',
}, },
{ {
name: 'T8 — base64-pipe-shell idiom (echo BLOB | base64 -d | sh)', // Split for the same reason as the pipe-to-shell name above.
name: 'T8 — base64-pipe-shell idiom (echo BLOB | base64 -d |' + ' sh)',
// Matches: echo|cat|printf <base64-blob> | base64 -d | <shell> // Matches: echo|cat|printf <base64-blob> | base64 -d | <shell>
// Common malware loader pattern that bypasses static name-matching by // Common malware loader pattern that bypasses static name-matching by
// delivering the destructive command as encoded text. // delivering the destructive command as encoded text.