llm-security/tests/lib
Kjell Tore Guttormsen 6d0f3c31fc
fix(policy): read policy.json only from the caller's own working tree
loadPolicy() read .llm-security/policy.json from whatever root it was
given, and every scanner passes the SCANNED TARGET: scan-orchestrator
(policyRoot = resolve(args.target)), entropy-scanner (thresholds and
suppression patterns), signature-scanner (sig.custom_rules_path and
enabled_families), trigger-scanner (phrase lists) and ast-taint-scanner
(enabled, python_path). A foreign/cloned target could raise its own
entropy thresholds, disable SIG families, supply its own SIG ruleset or
name the interpreter the AST scanner spawns — configuring the scan of
itself. Same defect class as S3b's .llm-security-ignore fix.

Chosen: move isOwnWorkingTree() to scanners/lib/own-working-tree.mjs (one
copy, reused by the orchestrator's ignore-file check) and make
loadPolicy() refuse an EXPLICIT root that is not the caller's own tree —
defaults plus one stderr line, same form as S3b — because one rule in one
function covers every scanner and a future call site cannot forget it.
The IMPLICIT root (CLAUDE_PROJECT_ROOT/cwd, what every hook uses) is the
caller's own project by construction and is read as before.
entropy-scanner's calibration.policy_source no longer reports an ignored
file as its source.

New tests/scanners/policy-scope.test.mjs was red on 0d37f5a (foreign
target: entropy finding silenced, custom SIG rule loaded, findings differ
from the same tree without policy.json, no stderr line) and is green now;
its own-tree scenario (known-positive) is green before and after. The 15
existing policy tests that placed own-tree fixtures under os.tmpdir() now
use tests/helpers/own-tree.mjs (fixture under $HOME, cwd set to it).

Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
2026-09-22 20:15:17 +02:00
..
audit-trail.test.mjs feat(llm-security)!: v8 Phase 3 step 1 - remove the deprecated mode env-vars 2026-08-09 10:17:47 +02:00
bash-normalize.test.mjs feat(ultraplan-local): v1.6.0 — /ultraresearch-local deep research command 2026-04-08 08:58:35 +02:00
build-zip.mjs feat(llm-security): /security ide-scan <url> — Marketplace/OpenVSX/direct VSIX (v6.4.0) 2026-04-17 17:16:26 +02:00
codepoints.test.mjs refactor(llm-security): v8 Phase 5 step 4 - swap codepoint tables to commons 2026-08-10 21:28:09 +02:00
commons-loader.test.mjs test(llm-security): v8 Phase 5 step 3 - invert the unvendored-commons test 2026-08-10 20:52:04 +02:00
conformance-corpus.test.mjs feat(llm-security): publish the spec 1.1 conformance declaration as an artifact 2026-08-11 14:21:09 +02:00
diff-engine-exact-pass.test.mjs fix(llm-security): misc scanner correctness — reflog FP, diff exact-pass, hex dedupe, SARIF version (#20,#22,#50,#54,#56) 2026-07-18 10:36:51 +02:00
distribution-stats.test.mjs feat(ultraplan-local): v1.6.0 — /ultraresearch-local deep research command 2026-04-08 08:58:35 +02:00
doc-consistency.test.mjs docs(llm-security): trim README badge row 8 -> 4 (repo-standard BADGE-COUNT) 2026-08-04 11:50:12 +02:00
file-discovery.test.mjs fix(llm-security): normalization/discovery evasion + SIG embedded-base64 & custom rules (#21,#23,#30,#36,#42,#52,#55) 2026-07-18 10:35:56 +02:00
git-clone-gitattributes.test.mjs feat(git-clone): E12 — .gitattributes filter-driver post-clone advisory 2026-04-30 15:29:13 +02:00
git-clone-sandbox.test.mjs fix(git-clone): accept HTTPS repo URLs on any host, not just GitHub 2026-09-22 14:14:39 +02:00
golden-baseline.test.mjs refactor(llm-security): build the SIG ruleset from vendored commons (malware-signatures 0.1.0) 2026-08-13 21:28:14 +02:00
injection-lexicon.test.mjs fix(llm-security): the ReDoS gate timed every pattern and reached 8 of 45 2026-08-13 20:30:31 +02:00
injection-patterns.test.mjs fix(llm-security): the ReDoS gate timed every pattern and reached 8 of 45 2026-08-13 20:30:31 +02:00
malware-signatures.test.mjs fix(llm-security): compileRules coerces a non-string pattern instead of dropping the rule 2026-08-13 21:51:10 +02:00
mcp-description-cache.test.mjs fix(llm-security): scanner robustness — ReDoS, MCP-stdout DoS, redirect loop, atomic writes (#24,#53,#31,#25,#51) 2026-07-18 10:15:11 +02:00
output.test.mjs feat(llm-security)!: v7.0.0 commit 6 — tests, docs, version bump 2026-04-19 22:26:35 +02:00
owasp-map.test.mjs refactor(llm-security): v8 Phase 5 step 4 - swap OWASP_MAP to commons 2026-08-11 12:53:48 +02:00
policy-loader.test.mjs fix(policy): read policy.json only from the caller's own working tree 2026-09-22 20:15:17 +02:00
secret-egress.test.mjs refactor(llm-security): build the secret table from vendored commons (secret-egress 0.3.0) 2026-08-13 21:10:14 +02:00
severity.test.mjs docs(severity): B3 — document info as scoring-inert (v7.2.0 prep) 2026-04-29 13:56:11 +02:00
skill-registry-atomic.test.mjs fix(llm-security): scanner robustness — ReDoS, MCP-stdout DoS, redirect loop, atomic writes (#24,#53,#31,#25,#51) 2026-07-18 10:15:11 +02:00
string-utils-hidden-unicode.test.mjs feat(unicode): E1 — extend hidden-Unicode detection to PUA-A and PUA-B 2026-04-29 14:18:49 +02:00
string-utils-homoglyph.test.mjs feat(injection): E16 — homoglyph NFKC fold before every pattern match 2026-04-29 14:22:05 +02:00
string-utils-tokens.test.mjs fix(dep): B7 — token-overlap typosquat heuristic alongside Levenshtein 2026-04-29 14:10:53 +02:00
string-utils.test.mjs fix(llm-security): normalization/discovery evasion + SIG embedded-base64 & custom rules (#21,#23,#30,#36,#42,#52,#55) 2026-07-18 10:35:56 +02:00
v8-env-removal.test.mjs feat(llm-security)!: v8 Phase 3 complete - riskScoreV1, posture heuristic, docs 2026-08-09 10:25:03 +02:00
workflow-yaml-state.test.mjs fix(llm-security): YAML/workflow parser divergence — block scalars + bare if: (#32,#33,#43) 2026-07-18 10:35:56 +02:00
yaml-frontmatter.test.mjs fix(llm-security): YAML/workflow parser divergence — block scalars + bare if: (#32,#33,#43) 2026-07-18 10:35:56 +02:00