ktg-plugin-marketplace/plugins/llm-security/examples/supply-chain-attack/expected-findings.md
Kjell Tore Guttormsen ca5a8cec67 feat(llm-security): add 3 more runnable threat examples [skip-docs]
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).
2026-05-05 15:01:20 +02:00

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`