Skip to content

fix(ai): hold AI loops to the check's hosts after a real-secrets run - #646

Merged
fclairamb merged 13 commits into
mainfrom
security/scan-specs-2026-10-23
Oct 23, 2026
Merged

fclairamb merged 13 commits into
mainfrom
security/scan-specs-2026-10-23

Conversation

@fclairamb

@fclairamb fclairamb commented Oct 23, 2026 •

Copy link
Copy Markdown
Owner

Fixes finding Q1 of the 2026-10-23 security scan (medium): the AI repair and generation loops could relay an encoded secret through the model to fetch_page or to a run without secrets. Scrubbing only removes exact matches, so this got past the runtime host allowlist from the P1 fix (#631).

Spec: specs/done/2026/10/2026-10-23-02-ai-loop-secret-relay-through-model.md.

What changed

  • Once a loop has made a run with real secret values, it is held to the check's own hosts: fetch_page only reaches those hosts, browser_snapshot is refused, and a blank-secrets run_script gets the same allowlist (repair and generation).
  • A refused host that was built at runtime is no longer named in the error the model sees.
  • Exact-match scrubbing stays as defence in depth. Comments, the P1 done spec and web/docs/docs/features/ai-authored-checks.md now say so.
  • Regression tests for the repair and generation paths and the refused host, with positive controls (a loop without a real-secrets run can still fetch any host; a repair on the previous host still runs with the real secret).
  • origin/main merged in.

Behaviour change: after a real-secrets run, repair and generation lose browser_snapshot and any fetch_page outside the check's hosts for the rest of that loop.

Batch gate: make build-backend lint-back test green.

Decided by autopilot

No open questions in the spec: the recommended proposal (1, plus 3 and 4) was implemented.

🤖 Generated with Claude Code

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
@codecov

codecov Bot commented Oct 23, 2026 •

Copy link
Copy Markdown

Codecov Report

❌ Patch coverage is 94.23077% with 3 lines in your changes missing coverage. Please review.
✅ Project coverage is 83.73%. Comparing base (077a0b7) to head (b3a512e).
⚠️ Report is 1 commits behind head on main.

Files with missing lines Patch % Lines
server/internal/aichecks/runner.go 88.23% 2 Missing ⚠️
server/internal/aichecks/tools.go 96.87% 1 Missing ⚠️
Additional details and impacted files
@@            Coverage Diff             @@
##             main     #646      +/-   ##
==========================================
+ Coverage   83.72%   83.73%   +0.01%     
==========================================
  Files        1269     1271       +2     
  Lines      129812   129936     +124     
==========================================
+ Hits       108682   108801     +119     
- Misses      21121    21126       +5     
  Partials        9        9              
Files with missing lines Coverage Δ
server/internal/aichecks/repair.go 87.39% <100.00%> (ø)
server/internal/aichecks/service.go 87.60% <100.00%> (ø)
server/internal/aichecks/tools.go 93.49% <96.87%> (+7.68%) ⬆️
server/internal/aichecks/runner.go 86.66% <88.23%> (+3.12%) ⬆️

... and 14 files with indirect coverage changes

🚀 New features to boost your workflow:
  • ❄️ Test Analytics: Detect flaky tests, report on failures, and find test suite problems.
  • 📦 JS Bundle Analysis: Save yourself from yourself by tracking and limiting bundle sizes in JS merges.

fclairamb and others added 4 commits October 23, 2026 09:24
Exact-match scrubbing cannot stop a script from handing the model an
encoded secret (base64.encode, reversal, slices). Once a generation or
repair loop has run a script with real secret values, every later
fetch_page, browser_snapshot and blank-secrets run_script of that loop
is held to the same host allowlist (the browser is refused), so the
model has nowhere to relay what it read.

A refused host built at runtime is now withheld from the error
("[a host built at runtime]"); a host the script or env spells out is
still named.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
…h the model

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
… the model

Co-Authored-By: Claude Sonnet 5.5 <noreply@anthropic.com>
@fclairamb fclairamb changed the title chore(specs): security scan findings fix(ai): hold AI loops to the check's hosts after a real-secrets run Oct 23, 2026
@fclairamb
fclairamb enabled auto-merge (squash) October 23, 2026 19:12
@fclairamb
fclairamb merged commit 7cf836d into main Oct 23, 2026
33 checks passed
@fclairamb
fclairamb deleted the security/scan-specs-2026-10-23 branch October 23, 2026 20:15
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant