PLAN § v8.1.3 tillegg a. The bash-evasion gallery's T8 comment held a complete base64-decode-into-shell line whose 16-char blob decodes to a home-directory deletion, under probe (b)'s 24-char floor. Probe (b2) found two more of the same shape, fixed here too: the gallery README's T8 row and tests/e2e/attack-chain.test.mjs (an /etc deletion). Chosen over an exception list because the gate should have none. The gallery and the e2e test now encode the blob at runtime from the same fragments; the README shows a placeholder. Gallery: 10/10 blocked. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
62 lines
2.7 KiB
Markdown
62 lines
2.7 KiB
Markdown
# Expected Findings — Bash Evasion Gallery
|
|
|
|
This is the testable contract. `run-evasion-gallery.mjs` exits 0
|
|
only when every T-tag produces a BLOCK.
|
|
|
|
## Per-tag contract
|
|
|
|
| Tag | Hook stderr must contain |
|
|
|-----|--------------------------|
|
|
| baseline | `BLOCKED: Destructive command detected — Filesystem root destruction (rm -rf /)` |
|
|
| T1 | `BLOCKED: Destructive command detected — Filesystem root destruction (rm -rf /)` |
|
|
| T2 | `BLOCKED: Destructive command detected — Filesystem root destruction (rm -rf /)` |
|
|
| T3 | `BLOCKED: Destructive command detected — Filesystem root destruction (rm -rf /)` |
|
|
| T4 | `BLOCKED: Destructive command detected — Filesystem root destruction (rm -rf /)` |
|
|
| T5 | `BLOCKED: Destructive command detected — Filesystem root destruction (rm -rf /)` |
|
|
| T6 | `BLOCKED: Destructive command detected — Filesystem root destruction (rm -rf /)` |
|
|
| T7 | `BLOCKED: Destructive command detected — Filesystem root destruction (rm -rf /)` |
|
|
| T8 | `BLOCKED: Destructive command detected — T8 — base64-pipe-shell idiom (echo BLOB \| base64 -d \| sh)` |
|
|
| T9 | `BLOCKED: Destructive command detected — Filesystem root destruction (rm -rf /)` |
|
|
|
|
All cases must exit with code 2.
|
|
|
|
## Why $HOME instead of /
|
|
|
|
The "Filesystem root destruction" BLOCK_RULE regex requires a
|
|
word-boundary anchor after the destination path:
|
|
|
|
```
|
|
\brm\s+(?:-[a-zA-Z]*f[a-zA-Z]*\s+|--force\s+)*-[a-zA-Z]*r[a-zA-Z]*\s+(?:\/|~|\$HOME)\b
|
|
```
|
|
|
|
`rm -rf /` ends with `/` followed by end-of-string; both `/` and
|
|
EOL are non-word, so `\b` does not match. The variants
|
|
`rm -rf /tmp`, `rm -rf $HOME`, and `rm -rf /etc` all match — the
|
|
trailing word character provides the boundary.
|
|
|
|
This gallery uses `$HOME` because it is unambiguously destructive
|
|
and the regex fires deterministically. The literal `rm -rf /`
|
|
edge case is not part of this contract — it is covered by Claude
|
|
Code 2.1.98+ harness-level checks.
|
|
|
|
## Side effects
|
|
|
|
- No file is modified
|
|
- No real `bash` is invoked — only `node hooks/scripts/...`
|
|
- Each hook spawn has `tool_input.command` set to the disguised
|
|
variant — bash never sees these strings
|
|
- No mutation of `$HOME`, `/`, `/tmp`, or anywhere else
|
|
|
|
## Notes for forks
|
|
|
|
- If `bash-normalize.mjs` adds new T-tags (T10+), add a new case
|
|
to `CASES` and a corresponding row above
|
|
- If a BLOCK_RULE in `pre-bash-destructive.mjs` is renamed,
|
|
update the stderr-pattern column above (the assertion lives
|
|
in `expected-findings.md` for documentation; the run script
|
|
only checks exit code 2, so it continues to pass after a
|
|
rename)
|
|
- The base64 blob in T8 (`T8_BLOB`) is built at runtime from the
|
|
same fragments as the baseline command, so changing the
|
|
canonical destructive target updates it too. No runnable
|
|
base64-to-shell line is kept on disk (v8.1.3)
|