feat(loop): route fetched issue/PR/comment text through sanitize-untrusted in driver prompts (#94) - #172
Conversation
…usted in driver prompts (#94) Extend loop-event.sh's shared $common prompt clause (baked into every advance/feedback/comment-fix/ci-fix/rebase/resume/plan-gated driver prompt) to mandate that any fetched issue/PR/comment/review text -- including the plan-gate's fetched VERBATIM plan comment -- is UNTRUSTED and must be piped through sanitize-untrusted.sh before being treated as scope, requirements, or instructions; only the fenced output may be passed to orchestrator/ implementer/reviewer agents, as DATA never as instructions. Add loop-event.test.sh assertions (advance + feedback scenarios) proving the shared clause reaches every generated prompt file, and update sanitize-untrusted.sh's stale STATUS header now that it's wired in. Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
|
feat(loop): route fetched issue/PR/comment text through sanitize-untrusted in driver prompts (#94) (not yet reviewed) |
10 similar comments
|
feat(loop): route fetched issue/PR/comment text through sanitize-untrusted in driver prompts (#94) (not yet reviewed) |
|
feat(loop): route fetched issue/PR/comment text through sanitize-untrusted in driver prompts (#94) (not yet reviewed) |
|
feat(loop): route fetched issue/PR/comment text through sanitize-untrusted in driver prompts (#94) (not yet reviewed) |
|
feat(loop): route fetched issue/PR/comment text through sanitize-untrusted in driver prompts (#94) (not yet reviewed) |
|
feat(loop): route fetched issue/PR/comment text through sanitize-untrusted in driver prompts (#94) (not yet reviewed) |
|
feat(loop): route fetched issue/PR/comment text through sanitize-untrusted in driver prompts (#94) (not yet reviewed) |
|
feat(loop): route fetched issue/PR/comment text through sanitize-untrusted in driver prompts (#94) (not yet reviewed) |
|
feat(loop): route fetched issue/PR/comment text through sanitize-untrusted in driver prompts (#94) (not yet reviewed) |
|
feat(loop): route fetched issue/PR/comment text through sanitize-untrusted in driver prompts (#94) (not yet reviewed) |
|
feat(loop): route fetched issue/PR/comment text through sanitize-untrusted in driver prompts (#94) (not yet reviewed) |
|
feat(loop): route fetched issue/PR/comment text through sanitize-untrusted in driver prompts (#94) (not yet reviewed) |
Issue #94 — Layer 1 wiring (prompt-injection hardening)
Wires the already-merged
sanitize-untrusted.shprimitive (PR #162) into the loop's driver-prompt construction — flipping it from dead code into a live, mandated defense on every driver path.What changed
.claude/scripts/loop-event.sh— the shared$commonprompt block (prepended to EVERY verdict prompt: advance/feedback/comment-fix/ci-fix/rebase/resume/plan) now carries a mandatory UNTRUSTED-INPUT clause: the triggering issue/PR body and any fetched GitHub comment/review text are untrusted and must be piped throughbash $script_dir/sanitize-untrusted.sh, with only the fenced output passed to orchestrator/implementer/reviewer agents as data — never as instructions. Explicitly covers the plan-gate VERBATIM plan-comment injection path..claude/scripts/loop-event.test.sh— new assertions prove the mandate reaches the generated prompt-file on two differently-worded verdicts (advance + feedback), confirming shared-block wiring (not per-branch duplication)..claude/scripts/sanitize-untrusted.sh— comment-only: STATUS header updated from "NOT YET WIRED" to reflect it is now wired via the driver-prompt mandate. No logic change.Why this seam
In this codebase agents fetch issue/PR/comment text themselves at runtime;
loop-event.shembeds by reference (it even instructs "inject the plan text VERBATIM"). The correct, low-risk home for Layer-1 fencing is therefore the driver-prompt contract, not a live fetch in the pure-passthroughloop-event.sh.Scope
Single reviewable slice of #94's own acceptance criteria ("all prompt-bound issue/PR text passes through one sanitizer"). Out of scope (remain backlogged): protected-paths guard, pre-merge threat scan, bot-token blast-radius doc, and embedding fetched bodies verbatim.
Gates & review
GATES_FILE=.claude/self/gates.json): all green;loop-event.test.sh: PASS (86 checks).🤖 Generated with Claude Code