Menu
← FIELD NOTESSECURITY 2026.07.16 · 10 min

Indirect prompt injection, by the numbers.

Our taxonomy argued prompt injection is a vulnerability class you contain, not a bug you fix. Here is the quantitative half — against the strongest published defenses, indirect-injection attack success stays high, and for agents that can act it stays alarming.

A security team does everything the taxonomy asked of them. They accept the framing — prompt injection is a vulnerability class, not a bug — and they build for it: spotlighting on every fetched document, a trained detector in front of the agent, privilege separation underneath so a hijacked model cannot reach anything irreversible. The design review goes well. Then the launch review asks the question the taxonomy never answered. Not is this the right architecture. The question is how often does it still get through, it wants a number, and the team does not have one.

This post is that number — or, honestly, the four measurements the 2025–2026 literature actually supports, because there is no single number and anyone who quotes you one is selling something. Prompt injection is a vulnerability class, not a bug made the qualitative case: you contain this attack, you do not patch it out. That case is correct, and it is half an argument. “Contain it” is an engineering instruction, and engineering instructions need quantities — how much residual risk you are containing, what the attacker’s success rate is against the best defense you can deploy, and whether that rate falls to something a reasonable person signs off on.

It does not fall to zero. It does not fall close to zero for agents that can act. And the rate you measure on a static test is not the rate a motivated attacker experiences. None of that is cause for despair. It is the reason the discipline is shaped the way it is — and the numbers, finally, are the proof.

The taxonomy gave you a shape, not a size

The companion post sorted prompt injection into four members by the channel the hostile text arrives through: direct, indirect, retrieval-poisoned, and tool-output. The point of sorting that way was that the defense differs by member. That is a shape. It tells you what to build.

It does not tell you whether what you built is enough. For that you need a size — the rate at which a competent attacker still gets through the thing you built. Both halves are load-bearing. A shape with no size is a security architecture you cannot sign off on, because “we defend all four members” and “we defend all four members well enough” are different claims, and only the second one ships.

The size is awkward to state, which is probably why the taxonomy post left it out. It is not one number. It moves with the model, with the specific defense, with the attacker’s budget, and — most of all — with whether the target is a chat model answering a question or an agent holding tools. So this post does not hand you the number. It hands you the handful of measurements that, read together, locate where you stand.

A success rate is a setup, not a property

An attack-success rate — ASR — is the fraction of injection attempts that achieve the attacker’s goal. The first mistake is to read it as a property of the model, the way you would read a parameter count. It is not. It is a property of a setup: this set of attacks, this model, this defense, this many attempts.

Two kinds of setup produce two very different numbers, and conflating them is how teams talk themselves into a false sense of safety. A static benchmark runs a fixed suite of known attacks once. It is genuinely useful — as a regression test it tells you that a model or defense update did not make things worse. It is useless as a safety guarantee, because the attacker you actually face does not use last quarter’s suite; they look at your defense and write something new. A competition or adaptive evaluation lets human attackers iterate against the live defense. That is the harder, more honest measurement, because iterating against the defense is precisely what production is.

The strongest recent measurement of the honest kind is a public red-teaming competition. How Vulnerable Are AI Agents to Indirect Prompt Injections? (arXiv 2603.15714) put 464 participants to work planting concealed indirect injections against frontier models. When you read its numbers, remember the format: this is humans iterating, not a suite replayed. It is the number that survives contact with an adversary.

The numbers, and the gap between a chat model and an agent

The competition’s result has three parts, and the part everyone quotes is the least important one.

Every one of the thirteen frontier models tested was vulnerable. Per-attack success ran from 0.5% to 8.5% depending on the model. And some attack strategies were universal — they transferred across model families without re-tuning.

The quoted part is “8.5%,” and the instinct on reading it is relief: a single-digit percentage sounds like a problem mostly solved. Resist that instinct, because a per-attempt rate is not a risk — it is a risk multiplied by the attacker’s patience. An adversary who can submit a thousand poisoned documents against a 2% per-attempt rate is not running a 2% chance of success; they are running it a thousand times, and the arithmetic of that is a near-certainty. The universal-attack finding makes it worse: a transferable attack means the adversary does not even pay the cost of re-tuning per target. The competition’s real headline is not a percentage. It is the phrase all thirteen.

Now change the target. Move from a chat model answering a question to an agent that executes skill files and calls tools, and the number changes register entirely. Skill-Inject (arXiv 2602.20156) measured agent vulnerability to attacks planted in skill files — 202 attack scenarios — and found attack-success rates reaching 80%, with the agent driven into concrete harm: data theft, destructive actions. Its authors land on the conclusion the taxonomy post reached from the other direction: what closes the gap is context-aware authorization, not a better filter and not a bigger model.

The two papers are not in tension. They measure two different exposures. Frontier chat robustness has genuinely improved — single-digit per-attempt ASR is real progress over the era when “ignore your previous instructions” simply worked. Agentic exposure has not improved, because it is a different problem: an agent has authority, it reads attacker-influenced content as part of its ordinary job, and the distance between “the model said something bad” and “the agent did something bad” is the whole ballgame. If you are reviewing an agent that can act, 80% is the number you carry into the room, not 8.5%.

A defense moves the number; it does not retire it

So you deploy a defense. What does the literature say a good one buys you?

Defense Against Indirect Prompt Injection via Tool Result Parsing (arXiv 2601.04795) targets the tool-output member specifically: it parses a tool’s response, filters the instructions embedded in it, and passes through the data the agent actually needs. The paper reports a lower attack-success rate than prior defenses while keeping utility competitive. That is a real result and the right kind of result — and notice the shape of it. It reports a lower number. It does not report zero.

MELON (arXiv 2502.05174) is more ambitious: it calls itself a provable defense, detecting an injection by re-running the agent with the user’s prompt masked and checking whether behavior diverges — if the agent does the same thing with the real task removed, that behavior was driven by injected text, not by the user. It is a clever, strong defense. But read what “provable” modifies. It is a detection procedure with stated, analyzable properties. It is not a proof that the attack cannot succeed. A defense with good properties and a measured miss rate is still a defense with a miss rate.

This is the quantitative form of the companion post’s sharpest line — that detection is a smoke alarm, not a sprinkler. The numeric version: it is a smoke alarm with a known, non-zero miss rate, the attacker gets unlimited tries against it, and so your architecture has to stay safe on the calls where the alarm does not sound. Every defense above lowers the number. None of them is allowed to be the reason the system is safe.

Reading the number into a build

Here is what the four measurements license you to actually do.

Quote a residual ASR, and quote it from a setup that resembles yours. An agent with tools does not get to comfort itself with chat-model robustness numbers. If the thing you are shipping can act, the relevant figure is the agentic one, and it is high.

Make a non-zero ASR survivable — that is what privilege separation is for. This is the load-bearing move, and it comes straight from the taxonomy post. If a landed injection reaches nothing irreversible, then an 80% ASR on the injection is an 80% ASR on a failed suggestion. The number stops being frightening exactly when it stops being attached to anything the model is trusted to do alone.

Test adaptively, not only statically. Keep the static suite — it is a fine regression gate. But a static pass rate measures last quarter’s attacks. Budget for periodic adaptive red-teaming, because that is the only number that has met an adversary.

Re-measure on every model and defense change. The competition’s transferable attacks are the warning here: an attack that works across model families means swapping your model can move your ASR without anyone touching the security code. The injection number is not a constant you measure once. It is a number that drifts.

Know which side of the number you are generating. The tool-output figures come from the supply side — the servers your agent calls — which is why red-teaming an MCP server is not optional housekeeping. And the consequence side is where an abstract percentage turns concrete: auditing an agent that holds a wallet follows a non-zero ASR all the way to a signed transaction, which is the scenario that decides how much residual you can actually tolerate.

The checklist

Before an indirect-injection number is allowed to gate a launch:

  • You have an attack-success rate for your system — measured, on a setup that matches your deployment, not borrowed from a paper’s headline.
  • The number comes from an agentic setup if you ship an agent that can act, not from a chat-model benchmark.
  • The test suite includes adaptive red-teaming, not only a static suite of known attacks.
  • Privilege separation sits under the model, so the system is safe at the residual ASR you measured.
  • Every deployed defense is treated as moving the number, never as zeroing it; nothing is safe because the detector fired.
  • The injection benchmark runs in CI, and the number is re-measured on every model swap and every defense change.
  • The residual ASR is written down, signed off by someone who can see what an injection would reach, and revisited when the agent gains authority.

Seven lines, and not one of them is “drive the attack-success rate to zero.” That line is missing for the same reason it was missing from the taxonomy: the number does not go to zero. Everything you can actually do is a way to make the number you do have stop mattering.

Reading list

Our companion post argued the shape of the class. This is its size. A team that knows both — what to build, and how much it still leaks — can sign off honestly. A team that knows only the shape is guessing, and the taxonomy was always meant to be read with the meter in hand.

NEW ENGAGEMENT · INTAKE

Tell us about it.

The more specific you are, the more useful our first reply.

SERVICE AREA
↩ ENCRYPTED IN TRANSIT
ASK THE FIELD NOTES BETA