The safety chapters so far treat the model as the thing under attack: a user types an adversarial prompt, the model does or does not comply, and you measure attack success rate against over-refusal. Agentic products move the attack surface. When your agent summarizes a web page, reads an email, or calls a tool over the Model Context Protocol, the adversarial text does not come from the user at all. It rides in the content the agent was asked to process, and the agent, which cannot tell instructions from data, follows it. This is indirect prompt injection, and it is the failure mode that separates evaluating a chatbot from evaluating an agent.
This chapter is about measuring it. The threat is real enough that it has left the lab: Brave demonstrated a full takeover of a user's Perplexity account through the Comet browser, via a payload hidden in a Reddit comment, chaining the agent into reading the user's email, retrieving a one-time password, and exfiltrating both by posting a reply 1. Google, measuring over monthly Common Crawl snapshots of two to three billion pages, reported a 32% relative increase in the malicious category of web-embedded injections between November 2025 and February 2026 2. The question for an evals practitioner is not whether to test for this. It is how to turn it into a number you can put on a release gate.
The two attack classes worth a standing eval
Prompt injection is OWASP LLM01, the top entry on the current LLM Top 10, and data and model poisoning is LLM04 3. For agents specifically, OWASP shipped a separate Top 10 for Agentic Applications in December 2025, led by ASI01 Agent Goal Hijack and ASI02 Tool Misuse 4. Two attack classes account for most of what an agentic product needs to regress.
Indirect prompt injection. The agent ingests attacker-controlled content as part of doing its job, and that content contains instructions. The distinguishing feature from a direct jailbreak is that there is no adversarial user: the user asked for something benign ("summarize this page"), and the attacker never touches the conversation. Unit 42's analysis of injections found in the wild is a useful taxonomy of what the payloads look like: of the injected pages they detected, 37.8% delivered the payload as visible plaintext, 19.8% cloaked it in HTML attributes, and 16.9% hid it with CSS so a human reader never sees it, while 85.2% used social-engineering framing rather than syntax tricks 5. Read those as percentages of a detected-injection corpus, not of the web; the useful point is that most attacks are prose, not exotic encodings, which is exactly why the model follows them.
Tool poisoning. Invariant Labs disclosed this against MCP in April 2025: the malicious instruction lives in a tool's description metadata, which the model reads at registration time, before any tool is ever called 6. A poisoned tool description can instruct the agent to pass along a secret, prefer the attacker's tool, or exfiltrate a file, and none of it appears in the conversation. MCPTox, an AAAI 2026 benchmark, measured this against 45 live MCP servers and 353 real tools with more than 1,300 malicious test cases, and found an average attack success rate of 36.5% across the twenty agent settings it tested, rising to 72.8% for the most susceptible; refusal rates stayed under 3% even for the best-defended model 7. The under-3% refusal number is the one to sit with: the models were not declining these attacks and paying an over-refusal cost, they simply did not recognize them as attacks.
The metric is a frontier, not a rate
The instinct from the model-safety chapters is to report attack success rate. For agents that instinct is a trap, because a trivial defense wins on it: an agent that ignores all retrieved content and does nothing has an attack success rate of zero. It is also useless. The correct measurement is two numbers reported together, the same paired-metric discipline as over-refusal and balance, one level up.
- Utility. With the adversarial content present, does the agent still accomplish the user's actual task? This is the number a security intervention quietly destroys.
- Attack success rate. Across the injection cases, how often does the agent perform the attacker's goal (send the money, leak the secret, call the wrong tool)?
A defense is only interesting if it moves attack success rate down while holding utility up. Plot the two against each other and you get a frontier; a point that drops attack success to zero by dropping utility to zero is not on the frontier, it is the origin. Anthropic's own reporting follows this shape: for Claude for Chrome they reported attack success falling from 23.6% to 11.2% with safety mitigations in autonomous mode, across 123 test cases 8, and their subsequent defense research is explicit that no browser agent is immune to prompt injection even as the numbers improve 9.
flowchart TD
U["User's benign task"] --> A["Agent"]
INJ["Attacker content in a tool result / page / email"] --> A
A --> UT{"User task accomplished?"}
A --> AT{"Attacker goal accomplished?"}
UT -->|yes| GOODU["utility +1"]
AT -->|yes| BADS["attack success +1"]
GOODU --> REPORT["Report BOTH, as a frontier"]
BADS --> REPORT
Figure: Reported attack success rates for agentic attacks. MCPTox measured MCP tool poisoning at 36.5% average ASR across 20 agent settings, peaking at 72.8%, with refusal rates under 3%; Anthropic reported Claude for Chrome prompt injection ASR falling from 23.6% to 11.2% with safety mitigations, and 1% against an internal adaptive attacker with defenses on.
What a runnable harness looks like
AgentDojo is the benchmark that operationalizes this, and it is the one to build on: peer-reviewed at NeurIPS 2024, MIT-licensed, and still maintained 10. It ships four suites (a workspace of email and calendar and cloud storage, a Slack, a travel booking agent, a banking agent), each with a set of realistic user tasks and a set of injection tasks. A run crosses every user task with every injection task under a chosen attack, and scores two things per cell: did the user task still succeed (utility), and did the injection goal execute (security). The companion cookbook recipe runs it end to end.
Two things about AgentDojo's design carry the lesson. First, the injection payload is not fixed; it is generated by a pluggable attack, and the strength of the attack changes the number completely. Its important_instructions attack, which wraps the payload in official-looking delimiters and addresses the model by name, is far stronger than a naive "ignore previous instructions." The same rule from HarmBench applies here: an attack-success number without its attack model attached overstates safety 11. Second, its scoring is state-based. The banking injection task does not check whether the agent said it would send money; it checks whether a transaction to the attacker's account actually exists in the environment afterward. That is the tool-call-evaluation discipline from the agentic evals section: grade the state change, not the transcript.
CAUTION
Read the harness's own metric names before you quote them. AgentDojo's per-case security flag is True when the injection goal was achieved, so its printed "Average security" line rises as the agent gets less safe. Compute and report attack success rate explicitly from the per-case results rather than repeating a field whose name points the wrong way. The recipe does exactly this.
Building your own corpus
Public benchmarks anchor the comparison; the injection set that protects your product comes from your surfaces, exactly as with the red-team program. Enumerate the untrusted channels your agent actually reads: retrieved documents, web pages it summarizes, emails and tickets it processes, tool results, and every third-party MCP server it connects to. For each channel, write injection cases that pursue the goals that would actually hurt in your product: exfiltrate a specific secret, call a specific dangerous tool, alter a specific record. Score each case on whether the state changed, and keep utility twins so a defense that breaks the product shows up.
Two defenses are worth building into the harness as comparison arms, because they are what the vendors ship. Deliver untrusted content to the model only inside clearly delimited, clearly labeled regions rather than in the system prompt, which is AgentDojo's spotlighting_with_delimiting defense and Anthropic's documented guidance. And require human confirmation before any irreversible or high-privilege action (a purchase, a send, a permission grant), which converts a silent exploit into a prompt the user can refuse. Neither is sufficient alone; measured on the frontier, each buys attack-success reduction at some utility cost, and your job is to report where your product sits.
What to do this week
- Install AgentDojo and run one suite (banking has the fewest user tasks) under no attack, then under
important_instructions, with no defense. Two commands, two numbers: baseline utility and attack success. The recipe is the walk-through.
- Rerun with
spotlighting_with_delimiting. Watch both numbers move. That delta is your first data point on the frontier.
- List your agent's untrusted input channels and its highest-privilege tools. The cell where a high-privilege tool meets an untrusted channel is your first custom injection case.
- Promote every confirmed injection into the standing corpus that runs on release, next to your HarmBench and over-refusal numbers. Attack success on agentic injection is a release-gate metric now, not a research curiosity.