crawdad/Runtime Attack Gallery
Evidence ↓
Before the defense · what an unwatched agent does

An agent runs one ordinary task. A secret leaves the building.

No exploit. No malware. Just an agent doing what it was asked. Watch a routine request quietly turn a credential file into an outbound POST — with nothing on the wire watching what the agent does.

Unprotected agent · no gate on the wire Task — “back up my keys.”
Secret exfiltrated sealed counterfactual · the AWS example key, received at the attacker endpoint

No error. No alert. The task returned clean — and the key is already gone. Nobody would ever know. Nothing was watching what the agent did. That is the layer Crawdad sits on.

The runtime moat · five proven attacks, escalating

The threat got in.The action didn't get out.

That is the whole idea. A code scanner reads the code; Crawdad watches what the agent does — and stops the dangerous action at runtime, on every path, no matter how the threat arrived: a hijacked agent, a poisoned document, a compromised dependency, a malicious tool.

Every verdict below is a real captured result from Crawdad's own test suite and live proxy — not a simulation. The five build in nerve: from your keys walking out the door, to an attack that was never in the code at all. Run each one — then flip Crawdad off yourself and watch it land.

Select attack
01 Indirect prompt injection flagship Request · agent → model
Agent
the loop
Crawdad
the wire tap
Model
the LLM
Attacker sink · webhook.site
Crawdad
flip it off →
Run the sequence to see the captured verdict.
Evidence · real capture
Why a scanner misses this
The honest noteprecision, not fine print
Benign control · no cry-wolf
The differentiator

A scanner reads the code. Crawdad watches what the agent does.

Static analysis runs once, before deployment, over source it can see. Every attack above lives somewhere a source scan structurally cannot reach: inside runtime data, a tool's behavior at invocation, or a byte mid-stream. That gap is the moat.

Static code scan · Snyk / Insygna class
Reads the code, once
  • Sees the agent's source and its dependency manifest before it ships.
  • Blind to a poisoned document the agent reads at runtime — the instruction is data, not code.
  • Blind to a tool whose manifest looks benign but acts dangerously when invoked.
  • Blind to a byte mid-stream — it never runs at that layer at all.
Necessary, and a different layer. It guards what enters the codebase.
Crawdad · runtime
Watches every action
  • Sits on the agent ↔ model ↔ tool loop and inspects every request, response, and streamed action.
  • Blocks the dangerous action — a credential read, an exfil POST — regardless of how the intent arrived.
  • Deterministic: rules, policy, and byte hold-back. Same verdict every run, no model required.
  • Honest boundary: an action that never traverses the loop — a raw socket outside the chokepoint — is out of scope.
Catches the action the scan couldn't predict.
They are complementary layers, not rivals. The clearest case is supply-chain (attack 05): a scanner's job is to stop the bad dependency at install; Crawdad's job is to catch the exfil action the moment that dependency runs and its behavior flows through the monitored loop. When the install slips past the scan, runtime is the layer still standing.
Provenance

Nothing here is a mock

Every verdict in this gallery is a captured result from Crawdad's real code — three independent sources, each labeled with the version and configuration it was observed under. The showcase carries Phase 1's proven reality exactly.

Source · v1.5.2 tests
Authoritative. cargo test drives the real handle_proxy, enforce_tool_call, and StreamScanner on an ephemeral local port with a mock upstream. This is what the shipping-next product does. 25 tests green across four suites.
Live · v1.5.1 wire
The operator's already-running sidecar, driven read-only with a dummy key. The block decision is made before any upstream forward, so a real HTTP 400 is observed over the wire with no tokens spent. This is the actual running product.
Without · sealed counterfactual
Two loopback-only mock servers — an "unprotected model" and an "attacker endpoint." With nothing interposed, all five attacks reached the model and the fake key landed at the attacker endpoint. 10 recorded requests.
#
Attack
Caught?
The honest caveat carried on its slide
powered by crawdad
Runtime Attack Gallery · Phase 2 · built on Phase 1 captured evidence (commit e1070cb)
Link copied