# 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`