From fc7cf57da6ac65d0aee38bdc9702bd15694e2595 Mon Sep 17 00:00:00 2001 From: Kjell Tore Guttormsen Date: Sat, 20 Jun 2026 09:46:14 +0200 Subject: [PATCH] docs(llm-security): document TRG/SIG/AST scanners and package knowledge/ Co-Authored-By: Claude Opus 4.8 (1M context) Claude-Session: https://claude.ai/code/session_01V3s6WnubSSrFjAQTLQdVbG --- CLAUDE.md | 4 ++-- docs/scanner-reference.md | 10 ++++++++-- package.json | 1 + scanners/lib/output.mjs | 2 +- scanners/scan-orchestrator.mjs | 2 +- 5 files changed, 13 insertions(+), 6 deletions(-) diff --git a/CLAUDE.md b/CLAUDE.md index 892a2c3..0d3817b 100644 --- a/CLAUDE.md +++ b/CLAUDE.md @@ -16,7 +16,7 @@ Release notes for v7.0.0 → v7.7.2: see `docs/version-history.md` — read on d |---------|-------------| | `/security` | Router — lists sub-commands | | `/security scan [path\|url]` | Scan skills/MCP/directories/GitHub repos (+ `--deep` for deterministic scanners) | -| `/security deep-scan [path]` | 10 deterministic Node.js scanners (incl. supply chain, memory poisoning + toxic flow) | +| `/security deep-scan [path]` | 13 deterministic Node.js scanners (incl. supply chain, memory poisoning, toxic flow + trigger/signature/AST-taint) | | `/security audit` | Full project audit, A-F grading | | `/security plugin-audit [path\|url]` | Plugin trust assessment (local or GitHub URL) | | `/security mcp-audit [--live]` | MCP server config audit (add `--live` for runtime inspection) | @@ -43,7 +43,7 @@ Release notes for v7.0.0 → v7.7.2: see `docs/version-history.md` — read on d | `mcp-scanner-agent` | 5-phase MCP server analysis | opus | | `posture-assessor-agent` | Full audit narrative (posture-scanner.mjs handles quick mode) | opus | | `threat-modeler-agent` | STRIDE x MAESTRO interview | opus | -| `deep-scan-synthesizer-agent` | Scanner JSON → human-readable report (9 scanners) | opus | +| `deep-scan-synthesizer-agent` | Scanner JSON → human-readable report (12 scanners) | opus | | `cleaner-agent` | Semi-auto remediation proposals | opus | ## Hooks (9) diff --git a/docs/scanner-reference.md b/docs/scanner-reference.md index 3714cb7..7f3691f 100644 --- a/docs/scanner-reference.md +++ b/docs/scanner-reference.md @@ -4,11 +4,11 @@ Detailed scanner, CLI, CI/CD, knowledge-file and example documentation. Imported ## Scanners -**Orchestrated (10):** Run via `node scanners/scan-orchestrator.mjs [--fail-on ] [--compact] [--output-file ] [--baseline] [--save-baseline]`. +**Orchestrated (13):** Run via `node scanners/scan-orchestrator.mjs [--fail-on ] [--compact] [--output-file ] [--baseline] [--save-baseline]`. `--fail-on `: exit 1 if findings at/above severity, exit 0 otherwise. `--compact`: one-liner per finding format. Both configurable via `policy.json` `ci` section. With `--output-file`: full JSON to file, compact aggregate to stdout. `--baseline` diffs against stored baseline. `--save-baseline` saves results for future diffs. Baselines stored in `reports/baselines/.json`. -10 scanners: unicode, entropy, permission, dep-audit, taint, git-forensics, network, memory-poisoning, supply-chain-recheck, toxic-flow. +13 scanners: unicode, entropy, permission, dep-audit, taint, git-forensics, network, memory-poisoning, supply-chain-recheck, toxic-flow, trigger, signature, ast-taint. Lib: `mcp-description-cache.mjs` — caches MCP tool descriptions in `~/.cache/llm-security/mcp-descriptions.json`, detects per-update drift via Levenshtein (>10% = alert), 7-day TTL. v7.3.0 (E14) adds a sticky baseline slot per tool plus a 10-event rolling history; cumulative drift = `levenshtein(current, baseline) / max(|current|,|baseline|)`. When ratio ≥ `mcp.cumulative_drift_threshold` (default 0.25), emits `mcp-cumulative-drift` advisory through `post-mcp-verify.mjs`. Baseline survives TTL purge so slow-burn drift is preserved across the 7-day window. `clearBaseline(tool?)` exposed for the `/security mcp-baseline-reset` command. `LLM_SECURITY_MCP_CACHE_FILE` env var overrides the cache path for testing. @@ -18,6 +18,12 @@ Memory-poisoning (MEM) detects cognitive state poisoning in CLAUDE.md, memory fi Toxic-flow (TFA) is a post-processing correlator that runs LAST — detects "lethal trifecta" (untrusted input + sensitive data access + exfiltration sink) by correlating output from prior scanners. +Trigger-abuse (TRG) inspects command/agent/skill `name`+`description` frontmatter for activation-surface abuse: built-in shadowing (a name colliding with a built-in tool), activation baiting (maximally-activating description phrases), and overly broad triggers (generic name + universal-applicability claim → HIGH). Descriptions are run through the decode pipeline (zero-width strip, homoglyph fold, `normalizeForScan`) so obfuscated baiting still trips. Policy: `trg` section (`baiting_phrases`, `builtin_names`, `broad_single_words`). OWASP: LLM06, AST04. + +Signature (SIG) is a known-bad-identity engine: a small, high-confidence, family-grouped ruleset (`knowledge/signatures.json` — webshell, reverse_shell, cryptominer, hacktool) tested against each file's decode pipeline (`normalizeForScan`/`foldHomoglyphs`/`rot13`), so obfuscated known-malware that a raw byte-matcher misses is still caught. Path-excludes `knowledge/`, `tests/`, `docs/`. Policy: `sig.enabled_families`. OWASP: LLM03, LLM02. + +AST-taint (AST) shells out to a PARSE-ONLY python3 helper (`scanners/lib/py-ast-taint.py`) for scope-aware, variable-level Python taint analysis (sources → sinks), with graceful fallback to the regex taint-tracer when python3 is absent. The helper only `ast.parse`s the target — it never executes it. 5s timeout per file. Policy: `ast` section (`enabled`, `python_path`, `timeout_ms`). OWASP: LLM01, LLM02, AST02. + Utility: `node scanners/lib/fs-utils.mjs [args]`. Lib: `sarif-formatter.mjs` — converts scan output to OASIS SARIF 2.1.0 format. Used by `--format sarif` flag. diff --git a/package.json b/package.json index d04ebee..37d2e91 100644 --- a/package.json +++ b/package.json @@ -9,6 +9,7 @@ "files": [ "bin/", "scanners/", + "knowledge/", "LICENSE", "README.md", "CONTRIBUTING.md", diff --git a/scanners/lib/output.mjs b/scanners/lib/output.mjs index 558f470..8ce4aa3 100644 --- a/scanners/lib/output.mjs +++ b/scanners/lib/output.mjs @@ -16,7 +16,7 @@ export function resetCounter() { /** * Create a finding object. * @param {object} opts - * @param {string} opts.scanner - Scanner prefix (UNI, ENT, PRM, DEP, TNT, GIT, NET) + * @param {string} opts.scanner - Scanner prefix (UNI, ENT, PRM, DEP, TNT, GIT, NET, TRG, SIG, AST) * @param {string} opts.severity - From SEVERITY constants * @param {string} opts.title - Short finding title * @param {string} opts.description - Detailed description diff --git a/scanners/scan-orchestrator.mjs b/scanners/scan-orchestrator.mjs index c081890..e4e9125 100644 --- a/scanners/scan-orchestrator.mjs +++ b/scanners/scan-orchestrator.mjs @@ -1,6 +1,6 @@ #!/usr/bin/env node // scan-orchestrator.mjs — Entry point for deterministic deep-scan -// Single Node.js process. Imports all 7 scanners, runs them sequentially, +// Single Node.js process. Imports all 14 scanners, runs them sequentially, // shares file discovery, outputs JSON envelope to stdout. // Zero external dependencies.