|
|
|
|
|
by blakec
99 days ago
|
|
The cache key collision is the part that keeps bugging me. Most CI/CD pipelines share a single npm cache across workflows. Cline's triage workflow restored a cache keyed on `${{ runner.os }}-npm-${{ hashFiles('package-lock.json') }}` — same key the release workflow used. So a poisoned cache from a low-privilege triage run propagated to the signed release build. No permission escalation needed. The cache is the escalation. The fix is workflow-scoped cache keys: # Before: shared key (vulnerable)
key: ${{ runner.os }}-npm-${{ hashFiles('package-lock.json') }}
# After: workflow-scoped key
key: ${{ runner.os }}-npm-triage-${{ hashFiles('package-lock.json') }}
But that only addresses one vector. The deeper problem is that every GitHub Action processing untrusted input (issue titles, PR bodies, comment text) is a prompt injection surface. The triage workflow fed the issue title into an LLM prompt. The attacker put executable instructions in the title. The LLM followed them. Classic indirect injection, new delivery mechanism.On the local side, macOS Seatbelt (sandbox-exec) can deny access to credential paths at the kernel level — the process tree physically can't touch ~/.ssh or ~/.aws regardless of what the agent gets tricked into doing. Doesn't help with cache poisoning, but it closes the exfiltration path on your own machine. ~2ms overhead per command, way lighter than spinning up a container every time. |
|