chore(llm-security): release v8.0.0 - version sync and changelog

Phase 6 of the approved v8.0.0 plan. HEAD was 45 commits past v7.8.3 with
every version-bearing file still reading 7.8.3 and no v8 tag anywhere.

Version sync: plugin.json, package.json, README badge, CLAUDE.md header.

CHANGELOG: [Unreleased] becomes [8.0.0] - 2026-09-18. It covered 3 of the
user-visible commits since v7.8.3; the other 18 fix/feat/refactor commits
are now recorded from their commit bodies - the commons extraction (five
tables, scanners/commons/ subtree, knowledge/signatures.json removed),
conformance spec 1.1, the golden-gate coverage relabel, and eight fixes
(script-tag recall, whole-table ReDoS gate and its own 8-of-45 blind spot,
Berry and nested lockfile-v1 misses, per-occurrence strip attribution,
legacy OpenAI keys, compileRules coercion, SIG self-flag, SARIF tags).
Counts verified against the loaded modules: 83 injection patterns, 19
secret shapes, 7 SIG rules.

SECURITY.md supported-versions table said 7.3.x Active; now 8.0.x Active,
7.0.x - 7.8.x best-effort. README gets the 8.0.0 row; CLAUDE.md gets the
v8.0.0 highlights and the test floor moves 2045+ to 2250+.

Tests: 2253 / 2247 pass / 0 fail / 6 skipped, exit 0, measured on HEAD
before the edits. The post-edit full run had 3 red, all timing ceilings,
under load average 60 from unrelated jobs on the machine; each passes
alone (460 ms of 1000, 370 ms of 2000, 2127 ms) and doc-consistency is
45/45 alone. The diff is docs and version strings only.

Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
This commit is contained in:
Kjell Tore Guttormsen 2026-09-18 00:16:19 +02:00
commit c14501e99c
6 changed files with 114 additions and 7 deletions

View file

@ -1,9 +1,11 @@
# LLM Security Plugin (v7.8.3)
# LLM Security Plugin (v8.0.0)
Security scanning, auditing, and threat modeling for Claude Code projects. 5 frameworks: OWASP LLM Top 10, Agentic AI Top 10 (ASI, 2026 edition), Skills Top 10 (AST), MCP Top 10, AI Agent Traps (DeepMind). 2045+ unit, integration, and end-to-end tests (`tests/e2e/` covers the multi-hook attack chain, multi-session state simulation, and the full scan-orchestrator pipeline); mutation-testing coverage not published.
Security scanning, auditing, and threat modeling for Claude Code projects. 5 frameworks: OWASP LLM Top 10, Agentic AI Top 10 (ASI, 2026 edition), Skills Top 10 (AST), MCP Top 10, AI Agent Traps (DeepMind). 2250+ unit, integration, and end-to-end tests (`tests/e2e/` covers the multi-hook attack chain, multi-session state simulation, and the full scan-orchestrator pipeline); mutation-testing coverage not published.
Release notes for v7.0.0 → v7.8.2: see `docs/version-history.md` — read on demand.
**v8.0.0 highlights** — Breaking cleanup + commons foundation. BREAKING: the four `LLM_SECURITY_*` env-vars deprecated in v7.3.0 (`INJECTION_MODE`, `TRIFECTA_MODE`, `ESCALATION_WINDOW`, `AUDIT_LOG`, plus `DEPRECATION_QUIET`) are removed — `.llm-security/policy.json` is the only source and a removed variable is **inert** (no warning, silently back to default); `riskScoreV1()` + `SEVERITY_WEIGHTS_V1` deleted (`riskScore()` v2 untouched). Structural, behaviour-preserving: five detection tables are now built from the pull-only vendored subtree `scanners/commons/` (`llm-security-commons`) instead of source literals — codepoint carriers (`scanners/lib/codepoints.mjs`), `OWASP_MAP` (`owasp-map.mjs`), the 83 injection patterns (`injection-lexicon.mjs`), the 19 fixed secret shapes (`secret-egress.mjs`), the 7 SIG rules (`malware-signatures.mjs`; `knowledge/signatures.json` removed). Each swap was measured position-by-position first and diffed record-for-record against the golden baseline (`scripts/golden-baseline.mjs`, `tests/golden/`). The commons root is resolved from the plugin directory only, **never** from a scanned target's policy (a substitutive override would let a hostile repo empty the detection corpus). **Loud failure is contract:** an unresolvable injection lexicon or SIG ruleset writes one stderr line and never throws — an empty table would be the v7.8.2 defect class (clean report, nothing run). Commons conformance spec 1.1 implemented (`tests/lib/conformance-corpus.test.mjs`; not-applicable verdict, derived declaration, anti-narrowing floor). Fixes: `<script>` recall hole + two quadratic `hybrid-xss` rows (whole-table ReDoS gate with inputs derived from each pattern's own prefix), Yarn Berry + nested lockfile-v1 misses in `supply-chain-recheck.mjs`, per-occurrence strip attribution in `content-extractor.mjs`, bare legacy OpenAI keys in `pre-edit-secrets.mjs`, `compileRules()` non-string coercion, SIG self-flag on vendored commons, SARIF multi-OWASP tags. Known open: bounded HTML patterns evade on >256 chars of attribute padding. 2253 tests.
**v7.8.3 highlights** — Security/correctness patch, no feature changes. 47 verified fixes from the v7.8.1/v7.8.2 completion-review MEDIUM tier (52 findings triaged; 3 missing-detector feature-requests and 1 non-defect scoped out; the #11 persistence detector and #27 AST-taint f-string recall deferred to v8). No CRITICAL/HIGH — every review-claimed HIGH downgraded to MEDIUM on re-verification. Supply-chain gate bypasses closed (npm bare-install blocklist skip, nested-key name derivation, yarn.lock false-BLOCK + Yarn Berry miss, `pip audit``pip-audit`); pathguard now covers `Edit`; HTML-pattern ReDoS (28s→4ms) and an MCP-stdout memory-exhaustion DoS fixed; toxic-flow/TRG false positives and a bare-`if:` Dependabot-spoof false negative fixed; YAML block-scalar key-leak and embedded-base64→SIG decode closed; docs/counts synced (14 orchestrated scanners, 16 posture categories, 72 red-team scenarios, 2013 tests).
**v7.8.2 highlights** — Security patch, no feature changes. Five defects from the v7.8.1 completion review, four sharing one failure mode: **the check reported success without running**. (1) `hooks/scripts/pre-bash-destructive.mjs` did not block `rm -rf /` or `rm -rf ~` — the target alternation `(?:\/|~|\$HOME)\b` ended in a word boundary that cannot hold after `/` or `~` at end-of-command, so the bare forms the rule is named for fell through to WARN (exit 0, command executed) while `/etc` and `$HOME` blocked normally, making the rule look functional from either end. (2) `scanners/entropy-scanner.mjs` matched its test/fixture suppression against the **absolute** path, so any ancestor directory named `test`/`spec`/`fixture`/`mock` silenced every entropy finding in the target while still returning status `ok`; it now keys off the relative path. (3) `scanners/ide-extension-scanner.mjs` guarded only `parseVSCodeExtension`'s bare-`null` failure signal, not `parseIntelliJPlugin`'s truthy `{ manifest: null, warnings }`, so any malformed JetBrains plugin dereferenced `manifest.hasSignature`; the TypeError escaped `mapConcurrent`'s unguarded `Promise.all` and aborted the scan of every other installed extension. Guard widened + per-extension fault isolation. (4) `scanners/content-extractor.mjs` — the remote-scan injection boundary — detected obfuscated injections but did not strip them: a decoded-only `match[0]` never occurs in the raw text, so the literal replace was a silent no-op and the payload reached the agent verbatim via `sanitized_content` alongside a finding announcing it. Removal is now line-level; unattributable multi-line payloads carry `unstripped: true`. This boundary had no direct test coverage before v7.8.2. (5) `scanners/lib/ide-extension-parser.mjs` emptied any plugin.xml field holding a character reference above `0x10FFFF` (`Number.isFinite` bounds nothing) — filed as HIGH, actually lower, since such a document is not well-formed XML.