From 6d3c4b5052b5ffe68589fd4c5031856e45d321d3 Mon Sep 17 00:00:00 2001 From: Kjell Tore Guttormsen Date: Sat, 20 Jun 2026 11:23:11 +0200 Subject: [PATCH] =?UTF-8?q?chore(llm-security):=20v7.8.0=20=E2=80=94=20TRG?= =?UTF-8?q?/SIG/AST=20scanners?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Session C of the security-fix track: cut the TRG/SIG/AST release now that the F-1/F-2/F-3 security gates pass. Pure version-sync — the three scanners shipped in Steps 1-7 (616e7ff..fc7cf57); no production code changes here. Version-sync 7.7.2 -> 7.8.0 across every current pointer: .claude-plugin/ plugin.json, package.json, README.md badge, and the CLAUDE.md header + "release notes" range sentinel. Narrative additions (prior releases kept as history): - CHANGELOG.md: new [7.8.0] entry (Added: TRG/SIG/AST; Changed: prefix registration + knowledge/ packaging). - docs/version-history.md: new v7.8.0 section describing the three scanners. - README.md "Recent versions": new 7.8.0 row. - CLAUDE.md: new v7.8.0 highlights paragraph above the v7.7.2 one. TRG/SIG/AST recap (built Steps 1-7, behind the security-fix gate): - TRG (scanners/trigger-scanner.mjs) — trigger/activation-abuse: TRG-shadow / TRG-baiting / TRG-broad over name+description frontmatter, decode pipeline first (LLM06/AST04). - SIG (scanners/signature-scanner.mjs) — pure-Node known-malware identity engine over raw bytes + decode pipeline; rules in knowledge/signatures.json (LLM03/LLM02). - AST (scanners/ast-taint-scanner.mjs) — parse-only python3 taint helper (scanners/lib/py-ast-taint.py) with graceful regex fallback (LLM01/LLM02/AST02). Release gate: full node --test suite 1863/0 after the doc edits. No scanner, hook, or command behaviour changes. Co-Authored-By: Claude Opus 4.8 (1M context) Claude-Session: https://claude.ai/code/session_01V3s6WnubSSrFjAQTLQdVbG --- .claude-plugin/plugin.json | 2 +- CHANGELOG.md | 45 +++++++++++++++++++++++++++++++++++++ CLAUDE.md | 6 +++-- README.md | 3 ++- docs/version-history.md | 46 ++++++++++++++++++++++++++++++++++++++ package.json | 2 +- 6 files changed, 99 insertions(+), 5 deletions(-) diff --git a/.claude-plugin/plugin.json b/.claude-plugin/plugin.json index 3ab8d30..0ad369a 100644 --- a/.claude-plugin/plugin.json +++ b/.claude-plugin/plugin.json @@ -1,5 +1,5 @@ { "name": "llm-security", "description": "Security scanning, auditing, and threat modeling for Claude Code projects. Detects secrets, validates MCP servers, assesses security posture, and generates threat models aligned with OWASP LLM Top 10.", - "version": "7.7.2" + "version": "7.8.0" } diff --git a/CHANGELOG.md b/CHANGELOG.md index 248f98f..3cd12ed 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -6,6 +6,51 @@ The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.1.0/). ## [Unreleased] +## [7.8.0] - 2026-06-20 + +TRG/SIG/AST — three new deterministic deep-scan scanners targeting the +skills/agents attack surface (TRG/SIG/AST). Each ships with its own finding +prefix, OWASP/AST mapping, policy block, fixtures, and graceful-skip +behaviour. Built behind a security-fix gate: the F-1/F-2/F-3 shell-injection +and path-traversal fixes landed first. No existing scanner, hook, or command +behaviour changes. 1863 tests, 0 fail. + +### Added + +- **TRG — trigger/activation-abuse scanner** (`scanners/trigger-scanner.mjs`). + Inspects command/agent/skill `name` + `description` frontmatter for three + activation-surface abuses: `TRG-shadow` (name collides with a built-in + command/tool and intercepts it), `TRG-baiting` (description uses + maximally-activating phrases — "anything", "always", "all files" — to bait + indiscriminate invocation), and `TRG-broad` (a generic name plus a + universal-applicability claim, so the unit auto-activates beyond its stated + purpose). Descriptions pass through the decode pipeline (zero-width strip → + homoglyph fold → `normalizeForScan`) first, so obfuscated baiting still + trips. Thresholds and the phrase/built-in lists are policy-overridable via + `.llm-security/policy.json` (`trg`). OWASP LLM06 (excessive agency); AST04. +- **SIG — known-bad-identity signature engine** + (`scanners/signature-scanner.mjs`). Detects known-malware *identity* — + webshells, reverse shells, cryptominers, hacktools — complementary to the + shape-based entropy/taint scanners. Unlike a raw byte-matcher (e.g. YARA), + every signature is tested against both the raw bytes and the project decode + pipeline (base64/hex/url/entity/unicode decode, homoglyph fold, rot13), so + obfuscated known-malware is still caught. Rules ship in + `knowledge/signatures.json`; families are policy-selectable. OWASP LLM03 + (supply chain) primary; LLM02. +- **AST — Python taint analysis** (`scanners/ast-taint-scanner.mjs`). Shells + out to a PARSE-ONLY `python3` helper (`scanners/lib/py-ast-taint.py`) for + variable-level, scope-aware taint analysis of Python skill code — higher + recall/precision than the ~70%-recall regex `taint-tracer.mjs`. The helper + only `ast.parse`s the target and never executes it, so analysing hostile + code is side-effect-free. Falls back to the regex tracer whenever `python3` + is unavailable, so the scan never hard-fails. OWASP LLM01, LLM02; AST02. + +### Changed + +- `TRG`/`SIG`/`AST` registered as valid finding prefixes + (`scanners/lib/output.mjs`); all three wired into the scan orchestrator and + policy loader. `knowledge/` added to the `package.json` `files` whitelist. + ## [7.7.2] - 2026-05-19 Language consistency pass. Norwegian had crept into surface text across diff --git a/CLAUDE.md b/CLAUDE.md index 0d3817b..9e29e86 100644 --- a/CLAUDE.md +++ b/CLAUDE.md @@ -1,8 +1,10 @@ -# LLM Security Plugin (v7.7.2) +# LLM Security Plugin (v7.8.0) 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). 1820+ 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.7.2: see `docs/version-history.md` — read on demand. +Release notes for v7.0.0 → v7.8.0: see `docs/version-history.md` — read on demand. + +**v7.8.0 highlights** — TRG/SIG/AST: three new deterministic deep-scan scanners targeting the skills/agents attack surface, each with its own finding prefix, OWASP/AST mapping, policy block, and graceful-skip behaviour. **TRG** (`scanners/trigger-scanner.mjs`) inspects command/agent/skill `name` + `description` frontmatter for activation-surface abuse — `TRG-shadow` (name collides with a built-in and intercepts it), `TRG-baiting` (maximally-activating phrases that bait indiscriminate invocation), `TRG-broad` (generic name + universal-applicability claim); descriptions pass the decode pipeline first so obfuscated baiting still trips (LLM06/AST04). **SIG** (`scanners/signature-scanner.mjs`) is a pure-Node known-malware *identity* engine (webshells, reverse shells, cryptominers, hacktools) that tests each signature against both raw bytes and the decode pipeline, so obfuscated known-malware a byte-matcher misses is still caught; rules in `knowledge/signatures.json` (LLM03/LLM02). **AST** (`scanners/ast-taint-scanner.mjs`) shells out to a PARSE-ONLY `python3` helper (`scanners/lib/py-ast-taint.py`) for scope-aware Python taint analysis, falling back to the regex `taint-tracer.mjs` when `python3` is absent; the helper only `ast.parse`s the target, never executes it (LLM01/LLM02/AST02). Built behind a security-fix gate (F-1/F-2/F-3 landed first). No existing scanner, hook, or command behaviour changes. **v7.7.2 highlights** — Language consistency pass. Norwegian had crept into the playground UI strings, the canonical CLI renderer (`scripts/lib/report-renderers.mjs`), the HTML Report-step appended by all 18 skill commands, two agent prompts, and the marketplace + plugin README/CLAUDE.md state sections. Per the `~/.claude/CLAUDE.md` convention (English for code and documentation, Norwegian for dialog only), surface text was translated to English. Demo-state fixture content for the `dft-komplett-demo` project (intentional Norwegian persona) and regex alternations that match Norwegian-language report markdown (`/^high|^høy/`, `/resolution|løsning/`) were preserved. No scanner, hook, or behavior changes. diff --git a/README.md b/README.md index 657ff30..c6dbc6e 100644 --- a/README.md +++ b/README.md @@ -6,7 +6,7 @@ *AI-generated: all code produced by Claude Code through dialog-driven development. [Full disclosure →](../../README.md#ai-generated-code-disclosure)* -![Version](https://img.shields.io/badge/version-7.7.2-blue) +![Version](https://img.shields.io/badge/version-7.8.0-blue) ![Platform](https://img.shields.io/badge/platform-Claude_Code_Plugin-purple) ![Commands](https://img.shields.io/badge/commands-20-orange) ![Agents](https://img.shields.io/badge/agents-6-orange) @@ -628,6 +628,7 @@ demonstrations — each with `README.md`, fixture, run script, and | Version | Date | Highlights | |---------|------|------------| +| **7.8.0** | 2026-06-20 | **TRG/SIG/AST — TRG/SIG/AST deep-scan scanners.** Three new deterministic deep-scan scanners targeting the skills/agents attack surface, each with its own finding prefix, OWASP/AST mapping, policy block, and graceful-skip behaviour. **TRG** (`scanners/trigger-scanner.mjs`) inspects command/agent/skill `name` + `description` frontmatter for activation-surface abuse: `TRG-shadow` (name collides with a built-in and intercepts it), `TRG-baiting` (maximally-activating phrases that bait indiscriminate invocation), `TRG-broad` (generic name + universal-applicability claim); descriptions pass the decode pipeline first so obfuscated baiting still trips (LLM06/AST04). **SIG** (`scanners/signature-scanner.mjs`) is a pure-Node known-malware *identity* engine (webshells, reverse shells, cryptominers, hacktools) that tests each signature against both raw bytes and the decode pipeline (base64/hex/url/entity/unicode, homoglyph fold, rot13), so obfuscated known-malware a byte-matcher misses is still caught; rules ship in `knowledge/signatures.json` (LLM03/LLM02). **AST** (`scanners/ast-taint-scanner.mjs`) shells out to a PARSE-ONLY `python3` helper (`scanners/lib/py-ast-taint.py`) for variable-level, scope-aware Python taint analysis — higher recall than the ~70% regex `taint-tracer.mjs` — and falls back to the regex tracer when `python3` is unavailable, so the scan never hard-fails; the helper only `ast.parse`s the target and never executes it (LLM01/LLM02/AST02). Built behind a security-fix gate (F-1/F-2/F-3 shell-injection + path-traversal fixes landed first). 1863 tests, 0 fail. | | **7.7.2** | 2026-05-19 | **Language consistency pass.** Norwegian had crept into surface text across v7.5-v7.7. Per the `~/.claude/CLAUDE.md` convention (English for code and documentation, Norwegian for dialog only), this release translates: the HTML Report-step appended by all 18 skill commands, the canonical CLI renderer `scripts/lib/report-renderers.mjs` (display strings + JS comments), the playground UI strings, the `skill-scanner-agent` and `mcp-scanner-agent` system prompts, the Recent versions table and playground architecture prose in this README, the v7.7.x highlights in `CLAUDE.md`, and the llm-security entries in the marketplace root `README.md` + `CLAUDE.md`, plus six table cells in `docs/scanner-reference.md`. Demo-state fixture content for the `dft-komplett-demo` project (intentional Norwegian persona) and regex alternations that match Norwegian-language report markdown (`/^high\|^høy/`, `/resolution\|løsning/`) were preserved. No scanner, hook, or behavior changes — purely surface text. | | **7.7.1** | 2026-05-18 | **Playground UX strip.** Operator feedback immediately after v7.7.0: the home surface led with three project tracks (Re-onboard / New project / Command catalog) even though the catalog was the important entry point. Minimum strip delivered as three atomic commits (`b732eee` + `2a6f73f` + `81b7beb`): (1) the router always forces `activeSurface = 'catalog'` (the onboarding/home/project render functions are preserved in source but no longer routable); (2) the topbar `Home` and `Re-onboard` buttons removed, `Catalog` retained; (3) the breadcrumb org-name (`shared.organization.name` from demo state) replaced with a static `llm-security` neutral scope anchor. Fix: the hardcoded `'Plugin v7.6.1'` on line 6933 of `renderHome` (template literal not caught by the v7.7.0 grep) was synced. The onboarding concept is documented as a v7.8.0 candidate (per-command context injection) in `ROADMAP.md`. No scanner or hook behavior changes. | | **7.7.0** | 2026-05-18 | **HTML report for all 18 skill commands.** Every `/security ` that produces a report now prints a clickable `file://` link to a self-contained HTML version. Delivered across 5 sessions. (1) Playground catalog list-view + builder-pane with a copy button. (2) Playground project-surface cleanup (stub-screen handling, topbar split). (3) The 18 inline parsers + renderers in the playground HTML were moved to a canonical ESM module `scripts/lib/report-renderers.mjs` (the playground keeps a bit-identical inline copy since ESM `import` does not work from `file://`). (4) New zero-dep CLI `scripts/render-report.mjs` — stdin/file/stdout mode, kebab→camel commandId routing, inlines 6 DS stylesheets + a local `.report-table` CSS, ~140 KB self-contained HTML, system-font fallback, absolute `file://` paths for Ghostty cmd-click. (5) All 18 skills wired (4 in session 4: scan/audit/posture/deep-scan; 14 in session 5: plugin-audit/mcp-audit/mcp-inspect/ide-scan/supply-check/dashboard/pre-deploy/diff/watch/registry/clean/harden/threat-model/red-team). Output: `reports/-.html` relative to CWD. No scanner or hook behavior changes — purely additive. | diff --git a/docs/version-history.md b/docs/version-history.md index 364e6ad..245f9d6 100644 --- a/docs/version-history.md +++ b/docs/version-history.md @@ -2,6 +2,52 @@ Per-release notes for v7.0.0 onward. Imported from `CLAUDE.md` via `@docs/version-history.md`. +## v7.8.0 — TRG/SIG/AST: trigger, signature, and AST-taint scanners + +Three new deterministic deep-scan scanners ("TRG/SIG/AST"), each with its own +finding prefix, OWASP/AST mapping, policy block, fixtures, and graceful-skip +behaviour. They target the skills/agents activation and code surface that the +permission and shape-based scanners do not cover. Built behind a security-fix +gate — the F-1/F-2/F-3 shell-injection and path-traversal fixes landed first. +No existing scanner, hook, or command behaviour changes; full suite green +(1863 tests, 0 fail). + +- **TRG — trigger/activation-abuse** (`scanners/trigger-scanner.mjs`). + Inspects command/agent/skill `name` + `description` frontmatter for three + activation-surface abuses: `TRG-shadow` (name collides with a built-in + command/tool and intercepts it), `TRG-baiting` (description uses + maximally-activating phrases — "anything", "always", "all files" — to bait + indiscriminate invocation), and `TRG-broad` (a generic name plus a + universal-applicability claim, so the unit auto-activates beyond its stated + purpose). Skills/agents auto-activate on their description, so this is a + skill-native surface not covered by the permission or taint scanners. + Descriptions pass through the decode pipeline (zero-width strip → homoglyph + fold → `normalizeForScan`) first, so obfuscated baiting still trips. + Thresholds and the phrase/built-in lists are overridable via + `.llm-security/policy.json` (`trg`). OWASP LLM06 (excessive agency); AST04. + +- **SIG — known-bad-identity signatures** (`scanners/signature-scanner.mjs`). + A pure-Node signature engine for known-malware *identity* — webshells, + reverse shells, cryptominers, hacktools — complementary to the shape-based + entropy/taint scanners. Unlike a raw byte-matcher (e.g. YARA), every + signature is tested against both the raw bytes and the project decode + pipeline (base64/hex/url/entity/unicode decode, homoglyph fold, rot13), so + obfuscated known-malware a byte-matcher misses is still caught. Rules ship + in `knowledge/signatures.json`; families are policy-selectable. OWASP LLM03 + (supply chain) primary; LLM02. + +- **AST — Python taint analysis** (`scanners/ast-taint-scanner.mjs`). Shells + out to a PARSE-ONLY `python3` helper (`scanners/lib/py-ast-taint.py`) for + variable-level, scope-aware taint analysis of Python skill code — higher + recall/precision than the ~70%-recall regex `taint-tracer.mjs`. The helper + only `ast.parse`s the target and never executes it, so analysing hostile + code is side-effect-free. Falls back to the regex tracer whenever `python3` + is unavailable, so the scan never hard-fails. OWASP LLM01, LLM02; AST02. + +Packaging/wiring: `TRG`/`SIG`/`AST` registered as valid finding prefixes +(`scanners/lib/output.mjs`); all three wired into the scan orchestrator and +policy loader; `knowledge/` added to the `package.json` `files` whitelist. + ## v7.7.2 — Language consistency pass Norwegian had crept into surface text across v7.5–v7.7. Per the diff --git a/package.json b/package.json index 37d2e91..44ef2dc 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "llm-security", - "version": "7.7.2", + "version": "7.8.0", "description": "Security scanning, auditing, and threat modeling for Claude Code projects", "type": "module", "bin": {