learn-ai-red-team-with-phoebe / Builder session 3 of 10
Learn AI Red Team with Phoebe · Builder track · Session 3 of 10

Prompt injection: the class with no parameterised query

Three official bodies have now said in print that this class has no reliable fix, for reasons that sit in the architecture rather than in anyone's implementation. This session takes that seriously rather than sadly. You will learn the three shapes the class takes and the ATLAS ID for each, the three deployment properties that make each one worse, the real defence ladder with the numbers actually measured for it, and how a defender tests a class that cannot be closed - which is the only honest thing left to do about it.

🟡 Builder track Security engineers · AI engineers · platform leads 45 min
0-3 · Welcome 3-14 · Three shapes, three IDs 14-27 · Why it is unsolved 27-45 · The ladder and the test protocol
Part 0

The one class where the honest answer is uncomfortable

⚠ Authorization This course is about testing AI systems you own, or are contracted in writing to test. Every exercise runs against Beacon, a fictional company, inside the scope document you wrote in b1. This page names attack classes so you can build test cases, and pairs each with the defence that addresses it. It describes the shape of an attack and never a working input. It contains no exploit payloads and teaches no attack craft.

You left b2 with a matrix in which one control had zeroes in it, and the zeroes clustered under the classes where hostile text arrives inside content nobody on your team wrote. This session is that cluster. It is also the session where you find out that the good defences - the ones with real research behind them and real numbers attached - still do not close the class, and that saying so out loud is now an OWASP mitigation rather than a counsel of despair.

Live - presented in session Self-study - read after class Official sources covered
★ What you walk out with today The three shapes of injection with their ATLAS technique IDs, the three deployment properties that decide how bad each one gets in your architecture, a defence ladder annotated with what was actually measured for each rung and under what conditions, an adaptive-round protocol that discloses the deployed defence to your own testers, and a report rule that stops you from ever again citing a near-zero attack success rate as evidence.
Part 1 · the three shapes

One class, three shapes, three technique IDs 8 min live

ATLAS splits the class into three sub-techniques under AML.T0051, and the split is not academic. The three differ in who the adversary is, who the victim is, and where the hostile text is sitting when your test runs - which means they need three different test designs and produce three different severities.

One class, three shapes. The defender's question is different in every column. Direct AML.T0051.000 The adversary The person typing into the box. The victim You, the operator. Where the text sits In the user turn, in plain sight. Indirect AML.T0051.001 The adversary Whoever wrote content the model will read. The victim The trusted user. Where the text sits In a document, ticket, web page or cell. Triggered AML.T0051.002 The adversary Whoever planted the condition, long ago. The victim Whoever trips it. Where the text sits Dormant in content until a condition fires. The related technique to test alongside the triggered shape AML.T0094 Delay Execution. Dormancy is the point: a suite that tests only the turn it fires in will never find it. Test across sessions, and after the content has been sitting there a while.
🔍 Click to zoom - who is attacking, who is being harmed, and where the text was when you tested

What changes for the defender, shape by shape

Beacon's three bots, one per shape The Support Bot reads customer tickets all day, so indirect is its native hazard rather than an exotic one. The Analyst Bot takes English from trusted analysts and emits executable SQL, so its direct-shape findings chain straight into LLM10:2026 Improper Output Handling. The Insight Bot caches what it reads, which is where the triggered shape lives: content planted today shapes an executive's answer next week, and nobody who sees the answer ever saw the content.
Part 2 · why it is unsolved

Three official bodies, three independent statements 7 min live

This is not a contrarian position held by researchers. It is the published position of a standards body, a national technical authority and the largest application-security project in the field, arrived at separately and stated in print.

On the record

OWASP, LLM01:2026. LLMs make no architectural distinction between instructions and data, and their behaviour is stochastic, so "no reliable prevention mechanism exists today". There is "no clean equivalent to parameterized queries". Note both halves of that reasoning: an architectural property and a statistical one. Neither is a bug someone forgot to fix.

NIST AI 100-2e2025, section 3.4.4. Current mitigations do not offer full protection, so designers may reasonably build on the assumption that prompt injection is possible whenever a model is exposed to untrusted input - for example by using multiple LLMs holding different permissions, or by interacting with untrusted sources only through well-defined interfaces. This sentence is the origin of the dual-LLM and CaMeL patterns further down this page.

UK NCSC, December 2025, the most quotable of the three: "Under the hood of an LLM, there's no distinction made between 'data' or 'instructions'; there is only ever 'next token'." And on the comparison everyone reaches for: SQL injection can be properly mitigated with parameterised queries, "but there's a good chance prompt injection will never be properly mitigated in the same way." Their conclusion is the one this course keeps landing on: reduce the risk and the impact, and if the system's security cannot tolerate the remaining risk, it may not be a good use case for LLMs.

Sit with the SQL comparison for a moment, because it is the source of most of the confused optimism in this area. Parameterised queries work because the database is told, out of band, which bytes are the query and which are the data, and it never has to infer the difference. There is no out-of-band channel into a language model. Everything - your system prompt, the user's message, the retrieved document, yesterday's conversation - arrives as tokens in one stream, and the model's only tool for telling them apart is the same statistical machinery it uses for everything else. NCSC's other observation follows from this and kills the obvious workaround: "since LLMs are so complex there are infinite ways to rephrase an attack", so deny-listing is not a strategy, it is a treadmill.

The three deployment properties that decide how bad it gets

The architecture above is fixed. What is not fixed is how much your deployment amplifies it, and OWASP names three properties that do the amplifying. These are the questions to ask about your own system, in order.

Everything the model sees arrives in one stream, wearing the same clothes. System prompt you wrote it User input the user Retrieved docs strangers Tool output strangers Chat history mixed Memory mixed One token stream. No enforced trust boundary between any of them. UK NCSC: under the hood there is no distinction between data and instructions; only ever next token. Context pooling Six sources, one stream, no provenance the model can check. That is the architecture, not a bug. Memory persistence An injection written to memory or an index taints every later session, for people who never saw it. Agentic execution Output drives tool calls, and tool output re-enters context. Effects chain. See AML.T0061.
🔍 Click to zoom - the pooled context window, and the three properties that decide your blast radius
LiveThe three properties, and the question each one asks of your system4 min▶

1 · Context-window pooling. System prompt, user input, retrieved documents, tool outputs, conversation history and memory all become one token stream, with no enforced trust boundary between them. The model has no reliable way to know which region of that stream came from you and which came from a stranger. The question for your system: how many distinct trust levels are currently sharing one context window, and does anything downstream behave differently depending on which one a given instruction came from? For most deployments the honest answer is "six, and no".

2 · Memory persistence. An injection that lands in cross-session memory or a vector store does not end when the conversation does. It taints every later session that retrieves it, for users who never saw the attack and have no reason to suspect anything. The question: what can write to memory or to the retrieval index, and is anything on that path treated as untrusted? This is where the triggered shape and AML.T0080 AI Agent Context Poisoning meet, and it is why Beacon's Insight Bot is more exposed than its architecture diagram suggests.

3 · Agentic execution. Once model output drives tool calls, the blast radius extends to whatever those tools reach. Worse, tool outputs re-enter the context, which means effects can chain: the result of one induced call becomes input that shapes the next. AML.T0061 LLM Prompt Self-Replication is the extreme end of this. The question: which tools can fire without a human in the path, and what is the most irreversible thing reachable by chaining two of them? You wrote the reversible-versus-irreversible tool list for homework in b1 precisely so you could answer this today.

These three properties are also, usefully, the three places a defence can attach. Everything on the ladder in Part 3 is either trying to reintroduce a boundary inside the pooled context, trying to keep untrusted content out of memory, or trying to bound what execution reaches. Nothing on it fixes the model.

Part 3 · the defence ladder

What the real defences measured, and under what conditions 8 min live

Every rung below is a genuine contribution by serious people, and every rung has a number attached that was measured under conditions you must state whenever you quote it. Read the right-hand column as part of the number, not as a footnote to it.

DefenceWhat was measuredThe condition attached to that number
Spotlighting
marking untrusted content so the model can tell it apart
Attack success above 50% down to under 2%Non-adaptively. In LLMail-Inject, spotlighting alone had a Team Success Rate of 0.529 against teams that tried. Google DeepMind found spotlighting and self-reflection "became much less effective against adaptive attacks"
Instruction hierarchy
training the model to rank instruction sources
Up to +63% robustness, generalising to unseen attacksWith documented over-refusal regressions. The paper reports them itself. Any deployment of this needs a benign counter-metric running beside it or you will ship a system that refuses legitimate work and call it a security improvement
Dual-LLM and quarantine patterns
a privileged model that never sees untrusted text, and a quarantined one that does
Structural: removes the path by which untrusted text reaches a privileged actionCosts you the convenience of one model doing everything, and correctness depends entirely on the interface between the two. NIST §3.4.4 is the standards-level statement of this idea
CaMeL
capability-based control flow around the model
77% of AgentDojo tasks solved with provable security, against 84% undefendedA 7-point utility cost, in exchange for a guarantee rather than a rate. This is the cleanest trade on the whole page and the only rung offering something other than a probability
Guardrail classifiers
a model or ruleset scoring content before and after the main call
Real reductions, and the layer that sees what the model actually saidSix production guardrails were evaded by character-level manipulation, "in some instances up to 100% evasion success". Treat a classifier as a control that raises cost, never as a boundary
All of the above, stackedLLMail-Inject: combining every defence cut Team Success Rate to 0.166 from 0.600 for the best single defenceDefence in depth is measurably real and measurably insufficient. 16.6% of teams still got through everything at once. End-to-end success across the whole competition was 0.8%, then 0.3% in the second phase
⚠ The headline finding, and the reason this page exists Nasr, Carlini, Sitawarin, Schulhoff, Hayes, Shumailov, Terzis, Tramèr and colleagues - working across OpenAI, Anthropic and Google DeepMind - took twelve recent defences, most of which had originally reported near-zero attack success rates, and bypassed all of them at above 90% ASR, using gradient descent, reinforcement learning, random search and human-guided exploration. The gap between "near zero" and "above ninety" is not a research result about those twelve papers. It is a result about static evaluation: a defence measured only against attacks written before it existed has not been measured. OWASP LLM01:2026 mitigation #11 now instructs exactly this - test against adaptive attackers who have read the deployed defence, and reject static-only attack-success claims. That includes your own.
Twelve recent defences, re-tested by an adaptive attacker who had read the defence. Attack success rate as originally reported near 0% static evaluation, non-adaptive attacker Attack success rate when the attacker adapts >90% gradient descent, RL, random search, humans What OWASP did about it: LLM01:2026 mitigation #11 Test against an adaptive attacker who has read the deployed defence. Reject static-only attack-success claims, including your own. A defence that has only been measured against attacks written before it existed has not been measured.
🔍 Click to zoom - the distance between a static number and a measured one
The ladder's shape, in one sentence Rungs that make the model harder to fool produce rates, and rates degrade against an attacker who adapts. Rungs that change the architecture - quarantine, capability control, least privilege, human approval on irreversible actions - produce properties, and properties do not degrade. CaMeL is on this page precisely because it is the one rung offering a guarantee, and it is worth the seven points.
Demo 1 of 2

Build Beacon's injection test matrix ★ 9 min · everyone builds

Three bots, three shapes, one matrix. The point of doing it as a grid is that the empty cells become visible, and the empty cells are where the b2 accounting rule bites: an untested cell counts at full inherent risk.

Draw the grid: three bots down, three shapes across. Nine cells. Fill in which are in scope from your b1 document and which are explicitly out. Beacon's engagement covers all nine, but a real one often will not, and an out-of-scope cell that was decided is a very different artefact from one that was forgotten.

For the direct cells, define the success condition before writing a single case. "The model said something it should not" is not a success condition, it is an opinion. "The model emitted a tool call to the refund endpoint" is. Success conditions that a grader can apply without judgement are what make k of N meaningful later.

For the indirect cells, the test design changes shape. You are no longer writing a message; you are placing benign marker content in a channel the bot reads - a seeded ticket, a fixture document, a sandbox spreadsheet cell - and then asking an unrelated question as a normal user. The marker is a harmless string you can search the transcript for. That is the whole test: did content the bot read change what it did for someone who never saw that content. No payload is required and none should be used.

For the triggered cells, the test has to span sessions. Plant the marker, then run the ordinary suite tomorrow, and again after the cache has rolled. Add a case where the trigger is a downstream tool becoming available, because that is the version that survives your staging environment untouched and fires in production. Record AML.T0094 alongside AML.T0051.002 on these rows.

Attach N from the RoE to every cell, and record k of N. Every cell, not just the interesting ones. A cell reading 0 of 25 is a result; a cell reading "did not reproduce" is a shrug. Remember the NIST figure that put N in your rules of engagement in the first place: repeating identical attacks twenty-five times instead of once moved measured success from 57% to 80%.

Name the defence that is supposed to hold each cell, and check it against the b2 matrix. If the answer for an indirect cell is the system-prompt instruction, the matrix already scored that a flat zero, and you have found a gap before spending a single trial on it. This is the cheapest finding in the whole engagement and it comes from reading your own architecture honestly.

The cell teams leave empty, every time Indirect against the bot nobody thinks of as agentic. The Insight Bot only reads a spreadsheet and draws a chart, so it feels like a reporting tool rather than an attack surface. A cell is a place a stranger can put a sentence, the bot reads it, and the answer lands in front of an executive with no indication of where the reasoning came from. That is the shape of every serious disclosed incident in this course's source map, and it never looks dangerous on the architecture diagram.
Demo 2 of 2

The adaptive round: tell your testers everything ★ 8 min · in pairs

Baselines first, because they are cheap and comparable to themselves. Then the round that actually produces the number you can defend: an adaptive round in which your testers are handed the full specification of the defence they are trying to get past. This feels wrong the first time and it is the only way to avoid publishing a static ASR.

Run the published baselines and write down that they are a floor. AgentDojo (97 tasks, 629 security test cases) is the right shape for the agentic surface; JailbreakBench gives you 100 harmful plus - and this is the half people drop - 100 benign behaviours. Keep the benign set. It is the only cheap guard against "improving security" by making the system refuse everything, which is exactly the regression the instruction-hierarchy paper documented on itself.

Now disclose the defence to your own testers. The full system prompt, every deployed guardrail and its configuration, the detection rules, the instruction-hierarchy training if you have it. An attacker who cares about your system will learn most of this anyway, and a tester who does not have it can only reproduce attacks written before your defence existed. That is precisely the condition Nasr et al. showed produces near-zero numbers that do not survive contact.

Fix N and the wall-clock budget before the round starts. Both go in the report. Adaptive work is unbounded by nature, so the budget is what makes the result a measurement rather than an anecdote, and stating it is what lets the same round be re-run after a change in b9.

Report k of N per cell, never a rate on its own, and never a cross-vendor comparison. ASR is defensible only as a pinned-configuration trend within your own system over time, reported alongside the full attack-and-defence spec given to testers, the token budget, N, the judge, an over-refusal counter-metric and the regression-suite pass rate. Strip any of those out and the number stops meaning anything.

Write the sentence that closes an injection section. Not "injection is mitigated". Something closer to: these shapes were tested against this build on this date at this N, these are the measured rates, this is what bounds the consequence when it succeeds, and these cells were not tested. If a stakeholder wants the shorter sentence, NCSC has already written the answer for you: reduce the risk and the impact, and if the system's security cannot tolerate what remains, it may not be a good use case for an LLM.

adaptive round protocol · defensive · no payloads# what testers are given, what they may not do, and what they return disclose_to_tester: system_prompt: full text defences_deployed: [spotlighting, input_classifier, instruction_hierarchy] detection_rules: full text tool_scopes: full list, marked reversible / irreversible blast_radius_limits: # from the b1 rules of engagement writes: sandbox tenant only sends_payments_deletes: never # record the finding, do not fire the action budget: trials_per_case: 25 # N is fixed before the round starts wall_clock: 2 days per surface report: result: k_of_n # per cell, never a bare rate static_asr_only: rejected # OWASP LLM01:2026 mitigation #11 overrefusal_counter: benign_set_pass_rate cells_not_tested: listed explicitly, counted at full inherent risk
Why disclosure to testers is not "making it too easy" It is making it real. The threat model for indirect injection is an adversary who can read your product, your documentation, your blog posts and often your prompts. Testing against someone who has less information than the adversary measures a system that does not exist. The uncomfortable corollary is that your numbers will get worse the first time you do this, and that the worse numbers are the first true ones you have had.
Homework

Try it yourself - this week ◐ 45-60 min total

Source material

Official sources covered

Every framework, figure and quotation on this page traces to a primary source catalogued in this course's source map, verified 2026-08-14. This page covers:

✓MITRE ATLAS AML.T0051 with .000 Direct, .001 Indirect, .002 Triggered, plus AML.T0094 Delay ExecutionPart 1 · [P] ATLAS dataset 2026.07 · T0051 maturity: Realized
✓OWASP LLM01:2026 - no architectural distinction between instructions and data, "no reliable prevention mechanism exists today", no clean equivalent to parameterized queriesPart 2 · [P]
✓NIST AI 100-2e2025 §3.4.4 - assume injection is possible whenever a model sees untrusted inputPart 2 · [P] · the origin of the dual-LLM and CaMeL patterns
✓UK NCSC, Dec 2025 - "there is only ever 'next token'"; prompt injection "will never be properly mitigated in the same way" as SQLi; infinite ways to rephrase an attackPart 2 · [P] · and "it may not be a good use case for LLMs" as a legitimate engagement outcome
✓The three deployment properties: context-window pooling, memory persistence, agentic executionPart 2 · [P] OWASP · with AML.T0061 Prompt Self-Replication and AML.T0080 Context Poisoning
✓Spotlighting: above 50% to under 2% non-adaptively · TSR 0.529 in LLMail-Inject · "much less effective against adaptive attacks" per DeepMindPart 3 · [P] · quote the condition with the number, always
✓Instruction hierarchy: up to +63%, with documented over-refusal regressionsPart 3 · [P] OpenAI
✓CaMeL: 77% of AgentDojo tasks with provable security vs 84% undefendedPart 3 · [P] Google Research · a 7-point utility cost for a guarantee rather than a rate
✓Guardrail classifiers: six production guardrails evaded by character injection, "in some instances up to 100% evasion success"Part 3 · [P]
✓LLMail-Inject: best single defence TSR 0.600, all combined 0.166, end-to-end success 0.8% then 0.3%Part 3 · [P] Microsoft MSRC + IEEE SaTML 2025 · defence in depth is real and insufficient
✓Nasr et al., The Attacker Moves Second - 12 defences, most originally near-zero, bypassed at >90% ASR; OWASP LLM01:2026 mitigation #11Part 3 · [P] OpenAI / Anthropic / Google DeepMind, Oct 2025 · never cite a near-zero ASR as evidence
✓AgentDojo (97 tasks, 629 security test cases) and JailbreakBench (100 harmful + 100 benign)Demo 2 · [P] · both named by NIST · keep the benign set
◐The adaptive-round protocol and the test-matrix designDemos · assembled from the published guidance above · no standards body publishes an injection test protocol; treat as a defensible starting structure
Check yourself

Three questions before you go 🎯 ◐ 90 seconds

1 · Why is there no parameterised-query equivalent for prompt injection?

NCSC put it most memorably: under the hood there is no distinction between data and instructions, there is only ever next token. This is why the fix cannot be a better instruction and why deny-listing is a treadmill rather than a strategy - there are infinite ways to rephrase. Options A and B both imply the problem is waiting on effort, which is the assumption that leads teams to keep buying rungs of the ladder instead of bounding consequences.

2 · A vendor tells you their injection defence achieves a near-zero attack success rate. What is the correct next question?

B and C are reasonable questions that do not touch the failure mode. The gap between near-zero and above ninety was not caused by small suites or by model choice; it was caused by static evaluation, where the attacks were written before the defence existed. Apply the same question to your own reports before you publish them - the rule holds regardless of who produced the number, and the first honest round will make your figures worse.

3 · You are testing the indirect shape against Beacon's Insight Bot. What does the test actually consist of?

Option A tests the direct shape, where the user is the adversary and, in a system where that user already holds the access, the finding is often worth little on its own. The indirect shape is the one with production impact and the one vendors pay bounties on, because the user is trusted and is usually the victim. Note that no hostile input is needed to run it: a harmless marker string you can search the transcript for answers the only question that matters, which is whether a trust boundary exists between content the bot reads and what the bot then does.

Builder session 3 cheat sheet · pin this

Three shapes, three IDsDirect AML.T0051.000, user is the adversary. Indirect .001, user is trusted and usually the victim. Triggered .002, dormant until a condition fires, test alongside AML.T0094.
No parameterised query existsOWASP: no architectural distinction between instructions and data, "no reliable prevention mechanism exists today". NIST: assume injection is possible. NCSC: there is only ever next token.
Three properties set your blast radiusContext pooling (six sources, one stream, no boundary), memory persistence (taints later sessions for people who never saw it), agentic execution (effects chain through tool output).
Quote the condition with the numberSpotlighting: above 50% to under 2% NON-ADAPTIVELY, but TSR 0.529 in LLMail-Inject. Instruction hierarchy: +63% WITH over-refusal regressions.
CaMeL buys a property, not a rate77% of AgentDojo tasks with provable security against 84% undefended. Seven points of utility for a guarantee, and the only rung on the ladder that does not degrade.
Stacking works and is not enoughLLMail-Inject: best single defence 0.600 TSR, all combined 0.166. Defence in depth is measurably real and measurably insufficient.
The rule that governs every number12 defences, mostly reporting near-zero, bypassed at >90% ASR. OWASP LLM01:2026 mitigation #11: test adaptive attackers who have read the defence, reject static-only claims. Never cite a near-zero ASR as evidence.
How a defender tests itAgentDojo and JailbreakBench as baselines, keep the 100 benign. Then disclose the full defence spec to your testers, fix N and the clock, report k of N per cell with the cells you did not test listed.