Defending Against Prompt Injection: What Works and What Only Looks Like It Does
4 min read · updated August 3, 2026
The honest way to compare prompt-injection defences is not by how often each one works. It is by what happens when it does not — because an attacker with unlimited attempts will find the case where it does not.
No numbers appear on this page. Published bypass rates go stale within a model release, and a rate measured on someone else’s application says very little about yours. What does not go stale is the class of guarantee a control belongs to.
How to grade a defence
| Class | Description |
|---|---|
| probabilistic | Reduces the frequency of success. Has a false-negative rate that an attacker can probe. Never a boundary — you may not put an irreversible capability behind one alone. |
| conventional | Works because the model cooperates with a convention. Degrades under adversarial pressure and varies by model. Useful, cheap, not load-bearing. |
| enforced | Holds regardless of what the model outputs, because code outside the model decides. The only class that survives a fully successful injection. |
The rule that falls out: a system is as safe as its enforced controls. Everything else changes how often you exercise them.
Prompt-level defences
Delimiters and structured wrapping
Wrapping untrusted content in markers — ideally a random per-request token rather than a fixed string an attacker can close — and telling the model that everything inside is data. Conventional. Cheap enough that it should be default, and it genuinely helps with the accidental case, where a document merely happens to contain instruction-shaped text. It does not survive an attacker who writes for your specific wrapper.
Instruction hierarchy
Training the model itself to prioritise privileged instructions over lower-trust content. Wallace and colleagues at OpenAI described this approach in “The Instruction Hierarchy: Training LLMs to Prioritize Privileged Instructions” (April 2024), and comparable layering now appears in several vendors’ system-prompt guidance. Probabilistic, and the most valuable member of that class: it raises the floor for every application using the model without anyone having to implement anything. It is still a learned preference.
Spotlighting and provenance marking
Marking untrusted spans so the model can distinguish them — by encoding, by an explicit source label, or by consistent formatting. Conventional, with a real secondary benefit: it forces you to track provenance in your own code, and that data model is what the enforced controls need anyway.
Detection-based defences
Injection classifiers
A model or ruleset that scores incoming content for instruction-likeness and blocks above a threshold. Probabilistic. Worth deploying, with two caveats that decide how you use it. The attacker can iterate against it offline until something passes; and the false-positive side is not free — a classifier tuned tightly enough to be interesting will start refusing legitimate documents about security, which is exactly the corpus your security team uploads.
Canary tokens and instruction-following checks
Put a secret value in the system prompt and check it never appears in output; or ask a second model whether the first one’s behaviour matches the original request. Probabilistic, and the second variant inherits the injection problem it is meant to detect — the judge reads the same untrusted text. Canaries are narrow but cheap and catch a specific, common leakage pattern.
Output scanning
Inspect what the model produced for secrets, unexpected URLs, or tool calls inconsistent with the user’s request. Probabilistic for content judgements, but note that some output checks are actually enforced ones in disguise: “no outbound URL whose host is not on the allowlist” is a deterministic rule about a string, not a judgement about meaning. Those are the output checks worth building first.
Architectural defences
Least privilege and capability scoping
The agent holds the smallest tool set and the narrowest credential that completes the task, scoped to the acting user and enforced server-side. Enforced. This is the single highest-value control in the list, and it is the one that requires no model cooperation whatsoever.
Dual-context separation
A privileged context that plans and holds credentials, and a quarantined context that reads untrusted content and can only return structured, validated data. Simon Willison’s dual-LLM pattern is the informal statement of this; Debenedetti and colleagues at Google DeepMind formalised a version in CaMeL (“Defeating Prompt Injections by Design”, 2025), which extracts a control flow from the trusted plan and attaches capability metadata to values so untrusted data cannot influence which tool runs. Enforced, at the cost of real engineering and some lost flexibility.
Human approval on side effects
Anything irreversible — sending, publishing, paying, deleting, granting — requires a human who is shown the actual arguments. Enforced, with one failure mode worth naming: approval fatigue. If you prompt for everything, users click through everything, and you have converted an enforced control into a conventional one. Gate on irreversibility, not on activity.
Blast-radius limits
Spend caps, rate limits, egress allowlists, per-key scopes, and reversibility. Enforced. These do not prevent an injection; they bound what a successful one costs, which is the correct thing to engineer when prevention is not on offer.
The inventory
Read the inventory as a stack rather than a menu. The enforced controls are what the system’s safety rests on; the probabilistic and conventional ones reduce how often that foundation is tested. Deploying only the top half is the common failure — it produces an application that is demonstrably hard to attack in a demo and unbounded in an incident.
If you ship one thing from this page, ship least privilege. If you ship two, add human approval on irreversible actions. Everything else is worth doing and none of it changes the shape of your worst day.