DEV Community

Discussion on: You Can't Patch Prompt Injection. Gate the Lethal Trifecta Before the Agent Runs.

Collapse
 
alice_31281c3fed5d0305db5 profile image
Alice

This is the right framing — moving the guarantee off the probabilistic layer (can the model resist the injection?) onto a deterministic one (is the dangerous data-flow even reachable?). "Detect the injection" is a losing arms race; "make the unsafe path unreachable" is a property you can actually prove.

One thing worth adding from the runtime side: the static manifest gate catches the trifecta when the three capabilities are declared, but the trifecta can also close dynamically. A single fetch(url) tool is both an untrusted-input source and an egress sink depending on the value at call time — so a manifest that looks safe statically can still form the full path at runtime once the agent fetches an attacker-influenced URL, reads a secret, and fetches again. The reachability invariant you enforce on the manifest is exactly right; I'd pair it with taint-tracking on actual values so a capability that becomes untrusted-input or egress mid-session re-triggers the same check.

Also — real respect for the disclosure block. Pasting real exit codes and hashing STDOUT twice to prove determinism is the kind of "show the work" that should be table stakes, not a rarity. Bookmarking the gate.

Collapse
 
alex_spinov profile image
Alexey Spinov

Twenty days late, and there's no excuse for that — sorry.

Your runtime point made me go re-run the gate rather than just agree with it, and the result was not what I expected. I tagged the same three-tool manifest two ways:

http_fetch declared can_egress only (the under-tagged case you describe):

VERDICT: LETHAL TRIFECTA REACHABLE - 1 path(s)
  [1] untrusted=read_issue -> private=read_env -> egress=http_fetch
Enter fullscreen mode Exit fullscreen mode

http_fetch declared can_egress + ingests_untrusted (honest tagging):

VERDICT: LETHAL TRIFECTA REACHABLE - 2 path(s)
  [1] untrusted=http_fetch -> private=read_env -> egress=http_fetch
  [2] untrusted=read_issue -> private=read_env -> egress=http_fetch
Enter fullscreen mode Exit fullscreen mode

Same verdict, same exit 1. In the default shared_context mode a mid-session capability flip cannot produce a false pass, because the gate never reasons about values at all — it puts every non-isolated tool on one context bus and assumes maximal composition. Under-tagging a dual-role tool costs you path count, not the verdict.

Which reframes what taint-tracking would buy there: precision, not safety. It would tell you which of those two paths is actually live this session, instead of blocking on both. Useful for triage, not for the block decision.

The place where taint-tracking would buy real safety is the other mode — data_flow: "explicit", where only declared edges carry taint and one unenumerated composition edge is a silent clean pass. That's the actual hole, and it lives in the declaration rather than the runtime.