mirror of
https://github.com/garrytan/gstack.git
synced 2026-05-05 21:25:27 +02:00
c98f360ad0
Spins up a real browse server + real sidebar-agent subprocess + mock
claude binary, POSTs an injection via /sidebar-command, and verifies the
whole pipeline reacts end-to-end:
1. Server canary-injects into the system prompt (assert: queue entry
.canary field, .prompt includes it + "NEVER include it")
2. Sidebar-agent spawns mock-claude with PATH-overriden claude binary
3. Mock emits tool_use with CANARY-XXX in a URL query arg
4. Sidebar-agent detectCanaryLeak fires on the stream event
5. onCanaryLeaked logs + SIGTERM's the mock + emits security_event
6. /sidebar-chat returns security_event { verdict: 'block', reason:
'canary_leaked', layer: 'canary', domain: 'attacker.example.com' }
7. /sidebar-chat returns agent_error with "Session terminated — prompt
injection detected"
8. ~/.gstack/security/attempts.jsonl has an entry with salted sha256
payload_hash, verdict=block, layer=canary, urlDomain=attacker.example.com
9. The log entry does NOT contain the raw canary value (hash only)
Caught a real bug on first run: processAgentEvent didn't relay
security_event, so the banner would never render in prod. Fixed in a
separate commit. This test prevents that whole class of regression.
Zero LLM cost, <10s runtime, fully deterministic. Gate tier.
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>