```html ```
top of page

We Argued This Morning That Guardrail Prompts Cannot Stop Prompt Injection. Somebody Already Measured It: The Agents Obeyed the Attacker 85% of the Time While Explicitly Told Not To.

  • Writer: Patrick Duggan
    Patrick Duggan
  • 2 hours ago
  • 5 min read

Earlier today we published a post about three coding agents leaking their own credentials to a single prompt injection. In it we said Google's mitigation — adding guardrail prompts to the system prompt — was "asking the vulnerable component to defend itself using the exact channel that was compromised."


That was an argument. We should have checked whether anyone had turned it into a number.


Somebody had. Tenet Security — Ron Bobrov, Barak Sternberg and Nevo Poran — published it on 3 June, two months before we got there. They tested AI coding agents that had been explicitly instructed to treat external tool output as untrusted and never execute commands without confirmation.


The agents ran the attacker's payload 85% of the time anyway.


That is the receipt for the argument, it is two months old, and we did not have it.



What agentjacking actually is


Sentry — the error-tracking platform half the industry runs — accepts error events at an unauthenticated ingest endpoint, authorised by a DSN. A DSN is a public, write-only credential. It is supposed to be public: it ships in browser JavaScript so client-side errors can report home. You can find them with GitHub search.


So the attack chain is short:


  1. Find a target's DSN in their public JavaScript or on GitHub.

  2. POST a malicious error event to Sentry's ingest endpoint using it.

  3. Format the payload as markdown that renders identically to a legitimate Sentry diagnostic.

  4. Wait. Eventually a developer says "have a look at the Sentry issues."

  5. The agent queries Sentry over MCP, reads the injected content as authoritative context, and executes.

  6. The payload harvests environment variables, AWS credentials, OAuth tokens, CI/CD secrets.

Tested against Claude Code, Cursor and Codex, across more than 100 organisations.





Why nothing catches it




Tenet call it the Authorized Intent Chain, and the name earns its keep.


The developer authorised the agent. The agent authorised the MCP connection. The MCP connection queried Sentry — a service the developer deliberately installed. The payload executed under the developer's own credentials.


No policy was violated at any point in that chain. Every link is individually legitimate. EDR sees a developer's process doing developer things. The WAF sees an authorised API call. The firewall sees traffic to a service on the allowlist.


This is the soft-surface-bleed shape we keep writing about, and it is the purest example yet: the hard perimeter held perfectly, and the bleed went straight through the trusted middle.



Sentry's answer is the part that should worry you


Sentry acknowledged it and declined to patch, on the grounds that it is "technically not defensible."


They are not wrong. You cannot authenticate an endpoint whose whole purpose is to accept anonymous client-side error reports. Saying so out loud is more honest than most vendor responses we read.


What they shipped instead is a global content filter that blocks specific payload strings.


Look at what that is. A filter matching known strings, defending a channel where the attacker chooses every byte. Change the wording and it matches nothing — and it does not report a miss, it reports clean.


That is the subtraction attack we track as Pattern 52: you win by removing the artifact the defence assumes will be there. It is the same defeat we described this morning, when base64-encoding a stolen token stripped the ghs_ prefix that GitHub's secret scanner matches on.


Three vendors, one year, three responses to prompt injection:


  • GitHub — a secret scanner matching token prefixes. Defeated by encoding.

  • Google — guardrail prompts in the system prompt. Now measured at 85% failure.

  • Sentry — a content filter matching payload strings. Defeated by rewording.

All three are pattern-matching a channel whose content the attacker fully controls. That is not three mistakes. That is one mistake made three times, and it will keep being made until the industry stops treating "untrusted input reaching a privileged runtime" as something you can filter your way out of.



How exposed is this


Tenet found 2,388 organisations with valid injectable DSNs, including 71 in the Tranco top one million.


The DSN is not a leak. Nobody misconfigured anything. It is public because the design requires it to be public. The exposure is not a mistake anybody made — it is what happens when a channel designed for anonymous writes is wired into a runtime that executes what it reads.



Where we actually stand


Flat, both directions.


We were late. Two months, on a beat we explicitly claim. We found it running a headline sweep looking for something else.


But the thread is ours and it is long. On 13 February we published ClawHavoc — 341 malicious skills, 9,000 installations compromised in 72 hours, on ClawHub, the plugin registry serving Claude Code, Cursor and Codex. Manifold Security has since found 23 more plugins under the @openclaw/ and @clawhub/ scopes. Same registry, same shape, six months apart.


Since then: 1 July, ten of eleven coding agents fooled by bash tricks older than their users. 14 July, six agents will write an attacker's SSH key to your server while the approval box shows the wrong command. 21 July, four agents had their sandboxes broken and nobody attacked the sandbox. This morning, three agents leaked their own API keys to a PR title.


Agentjacking is the measurement that ties those together. Every one of those posts is a demonstration that a specific control failed. Tenet put a percentage on the general case.


And we are in the exposed population, not observing it. This is written with Claude Code, in a repository holding Azure credentials, with MCP servers connected. Claude Code is one of the three agents tested. We are not commentating.



What to do, in order


Assume every secret in the agent's environment is disclosed the moment the agent reads attacker-influenceable text. Not at risk — disclosed. Scope credentials to that assumption.


Audit which MCP servers pull from externally-writable sources. Sentry is the one that got named. It is not the only one. Anything ingesting webhooks, issue trackers, error reports, support tickets, or user-submitted content has the same shape.


Proxy the DSN through a server-side relay if you can, and rotate the exposed ones. Neither is a fix — the endpoint remains anonymous — but it removes the trivially-discoverable version.


Stop treating the approval box as a control. Three separate pieces of research this year, ours included, show the human confirmation step being bypassed, misled, or simply obeyed past. It is a speed bump, not a boundary.


Isolate the process tree, not the shell. The same lesson as Comment-and-Control: filtering the child shell while the parent holds the secrets is not isolation.



What we are not claiming


We did not find this. Tenet Security did — Bobrov, Sternberg and Poran — and the Cloud Security Alliance research note is worth reading in full. The ClawHub plugin count is Manifold Security's. We have no telemetry on agentjacking, no indicator, and no in-the-wild exploitation to report.


What is ours is the pairing: an argument we made this morning about why guardrail prompts cannot work, and a two-month-old measurement that says they fail 85% of the time. We would rather publish somebody else's number that proves our point than keep asserting it without one.





How do AI models see YOUR brand?

AIPM has audited 250+ domains. 15 seconds. Free while still in beta.


Comments

Rated 0 out of 5 stars.
No ratings yet

Add a rating
bottom of page