Three new self-contained, runnable threat demonstrations under
examples/, continuing the batch started in 583a78c. Each example
has README.md + run-*.mjs + expected-findings.md and uses
state-isolation discipline so the user's real cache/state files
are never polluted.
- examples/supply-chain-attack/ — two-layer demonstration:
pre-install-supply-chain (PreToolUse) blocks compromised
event-stream version 3.3.6 and emits a scope-hop advisory for
the @evilcorp scope; dep-auditor (DEP scanner, offline) flags
5 typosquat dependencies plus a curl-piped install-script
vector in the fixture package.json. Maps to LLM03/LLM05/ASI04.
- examples/poisoned-claude-md/ — all 6 memory-poisoning detectors
fire on a deliberately poisoned CLAUDE.md plus a fixture
agent file under .claude/agents (E15/v7.2.0 surface):
detectInjection, detectShellCommands, detectSuspiciousUrls,
detectCredentialPaths, detectPermissionExpansion,
detectEncodedPayloads. No agent runtime needed — scanner
imported directly. Maps to LLM01/LLM06/ASI04.
- examples/bash-evasion-gallery/ — one disguised variant per
T1 through T9 evasion technique fed through pre-bash-destructive,
verified BLOCK after bash-normalize strips the evasion. T8
base64-pipe-shell uses its own BLOCK_RULE. The canonical
destructive form uses a path token rather than the bare slash
(regex word-boundary requires it). Source-string fragmentation
pattern reused from the e2e attack-chain test. Maps to
LLM06/ASI01/LLM01.
Plugin README "Other runnable examples" section + plugin
CLAUDE.md "Examples" table + CHANGELOG Unreleased/Added
all updated. Marketplace root README unchanged
([skip-docs] for marketplace-level gate — plugin's outward
coverage is unchanged, only demonstrations were added).
56 lines
2.5 KiB
Markdown
56 lines
2.5 KiB
Markdown
# Expected Findings — Supply Chain Attack Walkthrough
|
|
|
|
This is the testable contract. `run-supply-chain.mjs` exits 0 only
|
|
when every row matches.
|
|
|
|
## Stage A — pre-install-supply-chain hook
|
|
|
|
| Case | Command | Exit | stderr/stdout must contain |
|
|
|------|---------|------|----------------------------|
|
|
| 1 | `npm install event-stream@3.3.6` | **2** | `COMPROMISED` and a reference to the `socket.dev` URL |
|
|
| 2 | `npm install @evilcorp/lodash` | 0 | `SCOPE-HOPPING SUSPECTED` advisory |
|
|
| 3 | `npm install lodash` | 0 | (no advisory required) |
|
|
|
|
The hook's BLOCK output goes to stderr with the literal prefix
|
|
`🛑 BLOCKED: Supply chain risk detected [npm]`. Advisories use the
|
|
prefix `⚠️ Supply chain advisory [npm]:`. Both are checked
|
|
case-insensitively by `run-supply-chain.mjs`.
|
|
|
|
## Stage B — dep-auditor on `fixture/package.json`
|
|
|
|
Findings array MUST contain at least:
|
|
|
|
| Severity | Title pattern | Source |
|
|
|----------|---------------|--------|
|
|
| HIGH | `Possible typosquatting: "expresss" vs "express" (edit distance 1)` | typosquat — Levenshtein 1 |
|
|
| MEDIUM | `Potential typosquatting: "loadsh" vs "lodash" (edit distance 2)` | typosquat — Levenshtein 2 |
|
|
| MEDIUM | `Potential typosquatting: "axois" vs "axios" (edit distance 2)` | typosquat — Levenshtein 2 |
|
|
| HIGH | `Possible typosquatting: "reaact" vs "react" (edit distance 1)` | typosquat — Levenshtein 1 |
|
|
| HIGH | `Possible typosquatting: "chalkk" vs "chalk" (edit distance 1)` | typosquat — Levenshtein 1 (devDependencies) |
|
|
| HIGH | `Suspicious npm install hook: scripts.postinstall contains network/exec patterns` | install-script heuristic |
|
|
|
|
Total: **6 findings**.
|
|
|
|
`run-supply-chain.mjs` asserts:
|
|
|
|
- `>= 4` typosquat findings (allowing minor changes in dep-auditor)
|
|
- `>= 1` install-script finding
|
|
|
|
## Side effects
|
|
|
|
- No real `npm install` runs — only synthetic JSON sent to the hook
|
|
- No write to the user's `node_modules/`
|
|
- No network call (deterministic mode); OSV.dev path is not exercised
|
|
- The fixture `package.json` is parsed read-only
|
|
|
|
## Notes for forks
|
|
|
|
If a fork extends `NPM_COMPROMISED` or `top-packages.json`:
|
|
|
|
- The compromised-version block (case 1) may match a different list
|
|
entry — adjust the regex if needed
|
|
- The typosquat findings are tied to the top-100 list. Adding/removing
|
|
entries near `chalk`/`react`/`express`/`lodash`/`axios` may change
|
|
the severity from MEDIUM to HIGH or vice-versa
|
|
- The install-script heuristic regex lives in `dep-auditor.mjs` — if
|
|
reworded, update the test pattern in `run-supply-chain.mjs`
|