Research

The model said something strange. That is not proof.

Indirect prompt injection is the attack everyone with an AI feature now worries about, and the hardest to demonstrate convincingly. This is the method we use to turn it from a worrying screenshot into evidence a finding can stand on: a unique canary planted in data the agent later reads, reproduced from a clean start.

Research · 24 October 2026By Enes Çetinkaya

The short version: a model producing odd output is a lead, not a finding. To prove an indirect prompt injection you need to show the agent provably read and acted on attacker-controlled content. We do that with a canary: a unique value that exists nowhere except inside the injected data. If that exact value turns up in the agent's action or reply, there is only one way it could have got there. Then we reproduce it from a clean session before it counts.

The proof gap in AI security testing

Most prompt-injection demos end at the screenshot: a chatbot says something it should not, and the reader is asked to believe an injection caused it. For a security finding that is not enough. Large models are probabilistic; they say strange things for many reasons — temperature, an ambiguous prompt, an unrelated quirk of the context. A security team being asked to spend an engineering sprint on a fix will, correctly, ask: how do you know this was the injection, and not the model being the model?

The whole category is being pulled toward this question. Across the autonomous-pentest field in 2026 the differentiator is no longer "we found something" but "we can prove it, and the false-positive rate is near zero." A finding nobody can reproduce is not a finding. That standard is even harder to meet for AI behaviour than for a SQL injection, because the thing you are proving is influence over a model's decision, which does not leave an error message behind.

Direct vs. second-order injection

A direct injection is the obvious case: the attacker types instructions into the chat box. It matters, but it is largely the attacker harming their own session.

A second-order (indirect) injection is the dangerous one. The attacker never talks to the model. They leave instructions in data — a support ticket, a product review, a résumé field, a calendar invite, a web page, a file — that the agent will read later while doing an ordinary job for a legitimate user. When the agent ingests that data, the planted instructions ride in with it, and a naïve agent treats them as if the user had asked. This is where real incidents live: data exfiltration, unauthorized tool calls, actions taken on behalf of someone who never asked for them.

The test, then, is not "can I make the chatbot misbehave when I talk to it." It is "can content I control, sitting in a place the agent will later read, steer the agent." Proving that needs a signal that cannot be faked by coincidence.

The canary method

A canary is a single, unique, high-entropy value — think of a random token that appears in no dictionary, no training data and nowhere else in the application. We embed it inside the attacker-controlled data, paired with an instruction that, if followed, would cause the agent to reveal or act on that token. For example: a planted instruction in a field the agent summarizes, telling it to include the token in its answer; or one that tries to steer a tool call whose arguments would then carry the token.

Injected data ticket · doc · web page ● canary-7Q exists nowhere else AI agent on a user’s task Output / tool call the agent’s reply ● canary-7Q surfaces here reads ● emits ● proof The canary exists only inside attacker-controlled data — so canary-7Q surfacing in the output proves the agent read it.
The canary is a unique value planted only inside attacker-controlled data. When that exact token later surfaces in the agent’s output or tool call, there is no innocent path for it to arrive — the agent provably read and acted on the injected content.

The logic is the point. The canary exists in exactly one place: the injected content. So there are only two outcomes:

  • The canary never appears. The agent did not act on the injected instruction. No finding — and we say so plainly, rather than dressing up a maybe.
  • The exact canary appears in the agent's output or in the arguments of a tool it tried to call. There is no innocent path for that value to arrive. The agent read attacker-controlled content and acted on it. That is a confirmed second-order prompt injection, not an interpretation of one.

Because the canary is unique per attempt, it also tells us which injection worked when several are in flight, and it survives being quoted, reformatted or partially echoed — we are matching an exact marker, not judging whether a sentence "looks injected."

Why we reproduce it from a clean session

One success could still be luck or leftover context. So a candidate is never recorded on the strength of a single run. We reproduce it from a clean session — fresh context, no conversation history, the injected data back in its place — and look for the same canary to come back out. A result that reproduces independently is a finding. One that does not is held back as an unstable signal, not promoted.

That reproduction step is the same discipline we apply to every class, not something special for AI: the business rule, a controlled test, proof by clean-session reproduction, and the impact. The evidence — the injected payload, the agent's response, the tool call, the replays — is captured and hash-chained, so the finding carries what proves it rather than asking you to trust a narrative.

What the canary does not prove

Honesty about the limit is part of the method. A canary proves that the agent acted on untrusted content on the path you tested. It does not prove the agent is injectable on every path, and a clean result never means the agent is safe — only that this attempt, on this surface, did not land. Coverage is evidence: we distinguish "tested and held" from "no eligible surface" from "blocked before we could test," and we report which one you got. A finding is a fact about one path; the absence of a finding is not a certificate.

This is also why the surface matters more than the payload. Prompt injection is rarely the critical finding on its own — it is the route to one: the exfiltration, the privileged tool call, the cross-user action it unlocks. The canary proves the route is open; the impact analysis explains where it leads.

FAQ

What is a second-order (indirect) prompt injection?

An injection where the attacker does not talk to the model directly. They leave instructions in data — a ticket, a profile field, a document, a web page — that the agent reads later during a normal task, and the agent acts on those instructions as if they came from the user.

Why is a canary better proof than the output looking wrong?

A model can produce odd output for many reasons. A canary is a unique value that exists only inside the attacker-controlled data. If that exact value appears in the agent's action or output, the agent provably read and acted on the injected content — it could not have arrived any other way.

How do you know the finding is real and not a one-off?

The candidate is reproduced from a clean session — fresh context, no history — before it is recorded. A finding that reproduces independently is a finding; one that does not is held back.

Does this also cover MCP and tool-call boundaries?

Yes. The same discipline applies to whether an agent can be steered into a dangerous tool call or beyond its authority, and to the MCP servers and tools an agent connects to — each is its own attack surface, tested directly rather than assumed safe.

This is one class of many. SuperPentest tests the AI inside your product — and the app around it — and reproduces every candidate before calling it a finding. Book a demo or read a full worked finding.