diff --git a/CLAUDE.md b/CLAUDE.md index bb11c41..696909a 100644 --- a/CLAUDE.md +++ b/CLAUDE.md @@ -2,167 +2,7 @@ Security scanning, auditing, and threat modeling for Claude Code projects. 5 frameworks: OWASP LLM Top 10, Agentic AI Top 10 (ASI), Skills Top 10 (AST), MCP Top 10, AI Agent Traps (DeepMind). 1822+ 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. -**v7.0.0 — Severity-dominated risk scoring (v2 model, BREAKING).** Three changes target the false-positive cascade on real codebases (hyperframes.com gave `BLOCK / Extreme / 100`, ~70% noise): - -1. **Risk-score v2 formula** (`scanners/lib/severity.mjs`) — severity-dominated, log-scaled within tier. Replaces v1 sum-and-cap that collapsed every non-trivial scan to 100/Extreme. Tiers: critical → 70–95, high only → 40–65, medium only → 15–35, low only → 1–11. Verdict cutoffs realigned to new bands (BLOCK ≥65, WARNING ≥15). `info` findings are observability-only — counted in OWASP aggregates but contribute zero to risk_score, verdict, and riskBand (B3, v7.2.0 — was undocumented pre-7.2.0). See `severity.mjs` JSDoc for full contract. -2. **Rule-based entropy scanner with file-extension skip, 8 line-level suppression rules, and configurable policy** — extensions skipped (`.glsl/.frag/.vert/.shader/.wgsl/.css/.scss/.sass/.less/.svg/.min.*/.map`); line-suppression rules (GLSL keywords, CSS-in-JS, inline SVG, ffmpeg `filter_complex`, User-Agent strings, SQL DDL, `throw new Error(\`...\`)`, markdown image URLs). Configurable via `.llm-security/policy.json` `entropy` section (thresholds, `suppress_extensions`, `suppress_line_patterns`, `suppress_paths`). Envelope `calibration` block reports skip counters + effective thresholds + policy source. -3. **DEP typosquat allowlist expansion** — 22 npm + 5 PyPI entries for short-name tools that tripped Levenshtein detection on every modern codebase (`knip`, `oxlint`, `tsx`, `nx`, `rimraf`, `uv`, `ruff`, etc.). - -See `docs/security-hardening-guide.md` §6 for the calibration story. - -**v7.1.1 — Scan-rapport narrative coherence (patch).** Three coordinated -edits address the whiplash symptom that survived v7.0.0 (numbers fixed, -narrative still walked findings back as "false positive" in prose): -(a) `agents/skill-scanner-agent.md` Step 2.5 mandates context-first -severity assignment — every signal has exactly one disposition (suppressed -OR reported), no per-finding walk-back; (b) `templates/unified-report.md` -gains a `### Narrative Audit` block in Executive Summary surfacing -`summary.narrative_audit.suppressed_findings.{count, by_category}` from -the agent's trailing JSON; (c) both files updated from stale v1 -risk-formula constants to the v2 model that has been authoritative in -`severity.mjs` since v7.0.0. Counter is distinct from the existing -top-level `output.suppressed` (`.llm-security-ignore` rule integer). -Out-of-scope but flagged: `commands/scan.md:113-114` retains the v1 -formula; resolution deferred to Batch B. - -**v7.3.0 — MCP cumulative-drift baseline (in progress, Wave C of Batch C).** -Closes E14 from `docs/critical-review-2026-04-20.md`. The -`mcp-description-cache.mjs` schema gains a sticky `baseline` slot per -tool plus a 10-event rolling `history` array (FIFO). Cumulative drift = -`levenshtein(current, baseline) / max(|current|, |baseline|)`; when the -ratio crosses `mcp.cumulative_drift_threshold` (default 0.25), -`post-mcp-verify.mjs` emits a separate MEDIUM `mcp-cumulative-drift` -advisory. The existing per-update >10% drift signal is unchanged — both -fire independently. Slow-burn rug-pulls that keep each update under the -per-update threshold but cumulatively diverge from baseline are now -caught. Baseline survives the 7-day TTL purge so detection persists -across the full window. New `/security mcp-baseline-reset` slash command -(plus `scanners/mcp-baseline-reset.mjs` CLI: `--list`, `--target `, -or no-args clear-all) lets the user acknowledge a legitimate MCP server -upgrade — clearing the baseline causes the next call to seed a fresh -one from the incoming description; description, firstSeen, lastSeen, and -history are preserved for audit. `LLM_SECURITY_MCP_CACHE_FILE` env var -overrides the cache path for end-to-end testing without polluting the -user's real `~/.cache/llm-security/mcp-descriptions.json`. - -**v7.3.0 — Env-var deprecation warnings (D3 of Batch C, Wave D).** -Closes 8.7 from `.claude/projects/2026-04-29-batch-c-scope-finalize/plan.md`. -`scanners/lib/policy-loader.mjs` exports a new helper -`getPolicyValueWithEnvWarn(section, key, envVarName, defaultValue)` — -env still wins per Preferences (existing behaviour), but when both the -env-var AND the `policy.json` key are explicitly set, the helper emits a -single per-process stderr line: `[llm-security] Deprecation: env-var -${ENVVAR} will be removed in v8.0.0; policy.json key ${section}.${key} -also set — env wins for now. Suppress with LLM_SECURITY_DEPRECATION_QUIET=1.` -Module-scoped `Set` dedupes per env-var name across call-sites. Four -overlapping vars are wired through the helper: -`LLM_SECURITY_INJECTION_MODE` ↔ `injection.mode` (in -`pre-prompt-inject-scan.mjs`), `LLM_SECURITY_TRIFECTA_MODE` ↔ -`trifecta.mode` and `LLM_SECURITY_ESCALATION_WINDOW` ↔ -`trifecta.escalation_window` (in `post-session-guard.mjs`), -`LLM_SECURITY_AUDIT_LOG` ↔ `audit.log_path` (in -`scanners/lib/audit-trail.mjs`). `DEFAULT_POLICY` gains -`trifecta.escalation_window: 5` to close the gap noted in the plan -revisions table (M10). Env-only vars without policy.json equivalents -(`LLM_SECURITY_UPDATE_CHECK`, `LLM_SECURITY_PRECOMPACT_MODE`, -`LLM_SECURITY_PRECOMPACT_MAX_BYTES`, `LLM_SECURITY_IDE_ROOTS`, -`LLM_SECURITY_MCP_CACHE_FILE`) are unchanged — they emit no -deprecation signal because there is nothing to deprecate yet. - -**v7.5.0 — Playground (additive surface, no scanner/hook behavior changes).** -Single-file SPA at `playground/llm-security-playground.html` (~10 200 lines) -for onboarding, demo og workshop-bruk uten Claude Code-installasjon. Parser -+ renderer for alle 18 `produces_report=true`-kommandoer i `CATALOG`. State -i IndexedDB primær (`llm-security-playground-v1`) med localStorage-fallback, -sirkelfri Proxy + EventTarget store, microtask-batchet render. Theme-bootstrap -med FOUC-prevention. 4 overflater: onboarding (5 grupper) → home (3 tracks) -→ catalog (20 kommandoer) ⇄ project (rapporter / oversikt / kontekst / -eksport). Demo-state har tre prosjekter inline; `dft-komplett-demo` har alle -18 rapporter ferdig parsed for klikk-gjennom. Vendor-synket design-system -under `playground/vendor/playground-design-system/` (sjekksum-låst via -`MANIFEST.json`, redigeres aldri direkte). Test-fixtures under -`playground/test-fixtures/` (én markdown-fil per kommando) er kontrakt-anker -for parser-utvikling. Skjermdumper i `playground/screenshots/v7.5.0/`. -Eksponerte vinduer-globaler for testing/automasjon: `__store`, `__navigate`, -`__loadDemoState`, `__scheduleRender`, `__PARSERS`, `__RENDERERS`, `__CATALOG`, -`__inferVerdict`, `__inferKeyStats`, `__renderPageShell`, `__handlePasteImport`. -Inkluderer fix av `normalizeVerdictText` regex-rekkefølge: GO-WITH-CONDITIONS -sjekkes før GO så betinget verdict ikke kollapser til ALLOW. - -**v7.6.0 — Playground Tier 3-referanse-case (additive surface, no -scanner/hook behavior changes).** Playgroundet er nå en visuelt og -strukturelt fullført referanse-implementasjon for -`shared/playground-design-system/` Tier 3-supplementet. 8 nye Tier 3- -komponenter integrert i de 18 rapport-rendererne: `tfa-flow` + `tfa-leg` -+ `tfa-arrow` (lethal trifecta-kjede med `