From 614971c71a0e33c4364e1d3c5d2d5801ebf98aa3 Mon Sep 17 00:00:00 2001 From: Kjell Tore Guttormsen Date: Sat, 20 Jun 2026 11:10:24 +0200 Subject: [PATCH] =?UTF-8?q?chore(llm-security):=20STATE=20=E2=80=94=20Sess?= =?UTF-8?q?ion=20B=20(F-2=20+=20F-3)=20done;=20next=20=3D=20Session=20C=20?= =?UTF-8?q?(release)?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Co-Authored-By: Claude Opus 4.8 (1M context) Claude-Session: https://claude.ai/code/session_01V3s6WnubSSrFjAQTLQdVbG --- STATE.md | 57 ++++++++++++++++++++++++++------------------------------ 1 file changed, 26 insertions(+), 31 deletions(-) diff --git a/STATE.md b/STATE.md index 18ade2f..9ca837a 100644 --- a/STATE.md +++ b/STATE.md @@ -1,41 +1,36 @@ # STATE — llm-security **Active focus:** Security-fix track (from `docs/security-fix-brief-2026-06-20.md`). Critical review -DONE — brief verified sound. Implementing must-fixes over MULTIPLE sessions (context-limited). -**Session A (F-1 + F-5/F-6) DONE + pushed.** Next = Session B (F-2 + F-3). -TRG/SIG/AST (TRG/SIG/AST) shipped Steps 1–7; v7.8.0 release (Step 8) stays DEFERRED behind these fixes. +DONE. Must-fixes **F-1 / F-2 / F-3 ALL DONE** across Sessions A + B. **Next = Session C (release).** +TRG/SIG/AST (TRG/SIG/AST) shipped Steps 1–7; v7.8.0 release (Step 8) stays DEFERRED until Session C. ## Critical-review verdict (DONE — do NOT re-derive) -- **F-1 / F-2 / F-3 = MUST FIX.** Verified real, correctly diagnosed, fixes are local + mechanical. -- **F-5 / F-6 = cheap cleanup.** DONE — `--json` + `.orphaned_at` removed in Session A. -- **F-4 = optional** (LOW, by-design MCP spawn; a confirm-gate is a judgment call). -- One gap to add: F-2's prefix containment does NOT stop a symlink-escape — note it, but the prefix - check is the must-do part. +- **F-1 / F-2 / F-3 = MUST FIX. ALL DONE.** Verified real, fixes local + mechanical. +- **F-5 / F-6 = cheap cleanup. DONE** (Session A). +- **F-4 = optional** (LOW, by-design MCP spawn; confirm-gate is a judgment call) — still open. +- F-2 prefix containment does NOT stop a symlink-escape — noted inline in the fix; residual gap. -## Multi-session plan (TDD each: repro → red → green; full `node --test` green; gitleaks clean) -- **Session A — F-1 (CRITICAL) + cleanup. DONE (commit 5f50899, pushed).** `git()` in - `scanners/git-forensics.mjs` now `spawnSync('git', [...tokens], {cwd})` (no shell); ALL ~25 call - sites pass discrete arrays. Repro `tests/scanners/git-injection.test.mjs` (hostile `$(...)` - filename) RED→GREEN. F-5/F-6 `git rm` folded in. Suite 1860/0. -- **Session B — F-2 + F-3 (both HIGH). ← NEXT** - - F-2 `scanners/auto-cleaner.mjs` (sink ~`:776` `resolve(targetPath, f.file)`, write ~`:878-881`): - before write assert `absPath === targetPath || absPath.startsWith(targetPath + sep)`; else skip + - report. Test: a finding `file: "../escape.txt"` is refused, not written. - - F-3 `scanners/lib/supply-chain-data.mjs:221-227` (`execSafe` = `execSync`) reached via - `hooks/scripts/pre-install-supply-chain.mjs:254` → `inspectNpmPackage`: switch to - `spawnSync('npm',['view',spec,'--json'])` OR validate spec `^[@/A-Za-z0-9._-]+$` first. Test: - spec `foo;touch X` must not execute `touch`. -- **Session C — release.** Then Step 8 (v7.8.0) per - `docs/plans/trekplan-2026-06-20-TRG/SIG/AST-gap-analysis.md`. Optionally F-4 confirm-gate. +## Multi-session plan — FIXES COMPLETE +- **Session A — F-1 (CRITICAL) + F-5/F-6. DONE (5f50899, pushed).** `git()` → array-arg `spawnSync`. +- **Session B — F-2 + F-3 (both HIGH). DONE (commit 3f64aa5).** + - F-2 `scanners/auto-cleaner.mjs` (~:776): prefix-containment before write — a finding whose + `resolve(target, f.file)` escapes the tree is refused + reported skipped. Repro + `tests/scanners/auto-cleaner-traversal.test.mjs` (`../secret.txt`) RED→GREEN. + - F-3 `hooks/scripts/pre-install-supply-chain.mjs` `inspectNpmPackage`: `npm view` now + `spawnSync('npm',['view',spec,'--json'])` (no shell). Repro + `tests/hooks/supply-chain-injection.test.mjs` (`$(>/abs/PWNED)`) RED→GREEN. `execSafe` kept for + the static `npm audit --json` call (no interpolation). + - Suite 1863/0 (was 1860; +3). gitleaks clean. F-1 repro re-run GREEN (sink still closed). -## COLD START (next session = Session B) -1. `pwd` + `git status` (expect clean). Read `docs/security-fix-brief-2026-06-20.md` (F-2/F-3) + this STATE. -2. Start Session B TDD — F-2 first (failing repro: a `../escape.txt` finding must be refused), then F-3. -3. Mirror the Session-A pattern: array-arg `spawnSync` (style ref `scanners/lib/git-clone.mjs`), - repro-first, keep suite green, gitleaks clean, commit + push. +## COLD START (next session = Session C — RELEASE) +1. `pwd` + `git status`. Confirm 3f64aa5 + the STATE commit are present (and pushed — see notes). +2. Cut v7.8.0 (TRG/SIG/AST Step 8) now that the B− → A− security gates pass. Read + `docs/plans/trekplan-2026-06-20-TRG/SIG/AST-gap-analysis.md` Step 8 + `docs/version-history.md`. +3. Version-sync ALL refs before the bump commit (package.json, README badges, CHANGELOG, CLAUDE.md); + check consistency. Optionally add the F-4 confirm-gate. ## Continuity notes -- Disclosure hold MOOT: review `738770e` + brief `fea943b` already on `origin/main` (verified). No - special bundling — push fixes normally. +- Disclosure hold LIFTED: F-1 fix + `review-2026-06-20.md` + brief already on `origin/main`. Push + Session-B fixes normally. - origin = Forgejo `open/llm-security` (never GitHub). Push window: weekdays 20:00–23:00; weekends/ - holidays anytime. Suite now 1860/0 (was 1859; +1 F-1 regression test). + holidays anytime. Outside window at session end → commit locally, PARK the push, say so explicitly.