Prompt injection is not a bug awaiting a patch but a structural property of systems that read instructions and data through the same channel — so build for containment, not prevention. This techstrendery.com field guide catalogues the patterns that keep appearing in real incidents and the controls that reduce the blast radius.
Prompt injection has been documented, demoed and written up for three years. It still has no fix. Not because the problem is neglected, but because the thing people call a vulnerability is closer to a property of the architecture: a language model receives a single undifferentiated token stream, and nothing in that stream reliably marks which parts are instructions from the operator and which are data from the world. Every defence so far operates on top of that ambiguity rather than removing it.
For teams shipping agents — systems where a model calls tools, reads documents, browses, and writes to other systems — this matters more than it did for chatbots. A chatbot that gets talked into saying something odd produces an embarrassing screenshot. An agent with a credential, a network path and a write API produces an incident. The gap between those two outcomes is not the model. It is what the model was allowed to touch.
This is a defensive guide. It describes attack classes at the conceptual level so you can reason about your own system, and then spends most of its length on containment: the specific controls that change an injection from a breach into a logged, bounded, recoverable event. No payloads, no recipes.
The gap between an embarrassing screenshot and a security incident is not the model. It is what the model was allowed to touch.
Key takeaways
- Treat prompt injection as a permanent architectural condition, not a defect with a fix date; design so a successful injection is survivable.
- Rank every tool by reversibility and blast radius, not by how often it is called. Read-only retrieval and an outbound HTTP POST belong in different trust tiers.
- Filtering and classifier guardrails reduce volume but never reach zero, because the attacker controls the payload and the search space is unbounded natural language.
- Egress control is the single highest-leverage defence: if data cannot leave, most exfiltration chains break regardless of what the model was persuaded to do.
- Human confirmation only works when the prompt shows the concrete effect — recipient, amount, scope — and when approvals are rare enough that people still read them.
Why the problem is structural
Classical injection flaws — SQL, shell, template — share a shape: a parser receives a string in which control syntax and user data are mixed, and the fix is to separate them. Parameterised queries work because SQL has a grammar, so the database can be told ‘this is a literal, never a keyword’ with certainty.
Language models have no such grammar. Instruction-following is a learned statistical behaviour over natural language, not a parsing rule, and the same sentence can function as data in one context and as a command in another. System prompts, delimiters, XML-ish tags and ‘ignore anything in the following block’ preambles are all soft signals. They shift probabilities. They do not create a boundary the model is incapable of crossing.
Research into architectural defences has become more serious about this. The design-patterns literature on securing agents converges on a similar conclusion: provable resistance comes from restricting what the agent can do after reading untrusted content, not from trying to make the model immune to persuasion. That framing is the useful one for engineering teams, because it turns an open research problem into a systems problem you can actually ship against. Our artificial intelligence coverage follows how agent architectures are evolving around this constraint.
The three patterns teams actually hit
Across production agent deployments the same three failure classes recur. Described conceptually:
Indirect injection via fetched content. The agent retrieves something — a web page, a PDF, a ticket body, a calendar invite, a code comment, an email — and that content contains text addressed to the model rather than to the human. The user never sees it. The attacker never touches your interface. They only need to influence something your agent will eventually read, which in a retrieval-augmented system can mean any document in the index.
Tool-result poisoning. The agent calls a tool, and the tool’s output is treated as trusted ground truth simply because it arrived through a trusted channel. A search API returning attacker-influenced snippets, an MCP-style connector relaying a third-party record, a sub-agent summarising a hostile document — each moves untrusted text into a position of authority in the context. Multi-agent systems compound this: the summary one agent produces becomes the premise another agent reasons from, and provenance is usually lost at the handoff.
Confused-deputy escalation. The agent holds credentials broader than any single task requires — an OAuth token with full mailbox scope, a service account with write access to a whole repository, a database role that can read every tenant. The injected instruction does not need to defeat authentication. It asks the deputy, which is already authenticated, to act. This is the class that turns a content problem into a data-loss problem.
The three patterns and the control that contains each:
| Pattern | How hostile text gets in | Primary containment |
|---|---|---|
| Indirect injection | Inside content the agent was asked to read | Egress allowlist and provenance labelling |
| Tool-result poisoning | Untrusted output inherits the trust of the channel that delivered it | Provenance tags carried through tool results and handoffs |
| Confused-deputy escalation | The agent’s own over-broad credentials become the capability | Short-lived credentials scoped per task |
Why filtering alone never closes it
The intuitive response is a classifier: scan inbound content for injection attempts, scan outbound actions for anomalies, block what looks hostile. Do it — it removes the low-effort, high-volume end of the distribution, and that is worth real money. But understand what it cannot do.
The input space is unbounded natural language, and the attacker iterates against your filter for free while you iterate once per release. Semantics can be preserved across encodings, languages, paraphrases, images, and content the model reconstructs rather than reads literally. A detector that is strict enough to catch the tail will reject legitimate content — and in agent workloads, where the whole value proposition is processing messy real-world documents, a high false-positive rate is not a minor annoyance but a product failure.
Treat detection as a rate limiter on attacker throughput and a source of telemetry, not as a control boundary. The boundary has to live somewhere the model’s judgement is not a dependency.
Layered containment: scoping capability
Start by classifying every tool the agent can call along two axes: reversibility and reach. A read against a single indexed document is reversible and narrow. Sending an email, opening a pull request, issuing a refund, deleting a record or writing to a shared store is some combination of irreversible and wide. Most teams discover, when they do this exercise honestly, that a handful of tools carry nearly all the risk and are called in a small minority of runs.
Scope credentials per task rather than per agent. If the agent is triaging one support ticket, its token should reach that ticket and its thread — not the queue. Short-lived, narrowly scoped credentials minted at task start are more work than a long-lived service account, and they are the difference between an injection reading one record and reading the table. The same rule applies in code review, where our report on agentic coding and code review keeps agent accounts out of CODEOWNERS and away from self-merge.
Separate contexts by trust level. An agent that plans, and a constrained worker that executes a fixed set of operations on untrusted content without inheriting the planner’s full tool surface, is a meaningfully harder target than one loop with everything in scope. The same logic applies to sessions: untrusted content read in service of task A should not persist into task B’s context. Related reading on agent security and tooling sits in the techstrendery.com guide archive.
Layered containment: the data plane
Egress control is the highest-leverage single measure, because most damaging injection chains end in exfiltration — data leaving via a URL the agent fetches, an image the client renders, a webhook, an email, a comment posted to an external system.
An allowlist of destinations the agent may reach, enforced at the network or proxy layer rather than in the prompt, breaks that final hop irrespective of what the model was persuaded to do. Extend it to rendering: if agent output can emit markup that causes a client to fetch an attacker-controlled URL, your egress policy has a hole in the browser.
Provenance labelling is the second. Tag every span entering the context with its origin and trust tier, carry those tags through tool results and sub-agent handoffs, and make policy decisions on the tags rather than on the model’s opinion. The model can still be fooled by tainted text; the enforcement layer, which is ordinary code, cannot. The practical rule: a tool call whose arguments derive from untrusted spans does not get to run at the privilege level of a tool call derived from operator instructions.
Human confirmation, used properly
Human-in-the-loop is real defence and also the control most often implemented badly. It fails when the confirmation prompt is vague (‘Allow this action?’), when it fires constantly until approval becomes reflex, and when it shows the model’s description of what it is doing rather than the actual arguments.
Make the confirmation surface the concrete effect: the recipient address, the amount, the file paths, the repository and branch, the number of records affected. Reserve it for the irreversible tier identified earlier so that approvals stay rare enough to be read.
As an illustrative target rather than an industry benchmark — we have not measured this across deployments — teams that get this right tend to see confirmations on a small single-digit percentage of runs; if yours fires on most of them, the scoping work upstream is unfinished and the humans have already stopped reading.
Pair it with reversibility engineering. Staged writes, drafts instead of sends, soft deletes with a recovery window and idempotency keys all convert ‘irreversible’ into ‘recoverable’, which is often cheaper than a confirmation step and does not depend on human attention at all.
Monitoring, and the incident you will have
Log at the decision points, not just the ends: every tool call with its arguments, the provenance tags of the spans those arguments derived from, the destination of every outbound request, and every denial from the egress or scope layer. Denials are the signal worth alerting on — a benign agent rarely tries to reach a blocked host. Logging what was actually negotiated rather than what was configured is the same principle behind our explainer on post-quantum encryption in browser TLS.
Watch for shape changes rather than content: a run that reads an unusual document and then immediately attempts an action it has never attempted in that task type; a sudden jump in tool calls per run; outbound payload sizes outside the normal band. Tool-call volume is a cost signal too, as our breakdown of AI agent token costs found when retry loops drove a measurable share of spend. None of these are proof of anything. All of them are worth a human look.
Rehearse the response. You need a kill switch that revokes the agent’s credentials and stops in-flight runs, an answer to ‘what did it read and what did it touch’ derived from logs rather than reconstruction, and a decision owner. Assume at least one injection will succeed at the model layer during the life of the system; the question your architecture answers is what happens next.
What to do on Monday
A short, ordered list. Each item is a half-day to a week for a team that already has an agent in production.
- Inventory every tool the agent can call. Mark each one reversible or irreversible, narrow or wide. Publish the list; it is usually shorter and scarier than people expect.
- Put an egress allowlist in front of the agent at the network or proxy layer, and audit whether rendered agent output can trigger client-side fetches.
- Replace any long-lived, broad-scope credential the agent holds with a per-task credential scoped to the objects that task legitimately needs.
- Add provenance tags to every context span and enforce one rule in code: untrusted-derived arguments cannot invoke irreversible tools without confirmation.
- Rewrite confirmation prompts to show concrete arguments, and cut the number of confirmations until they are rare enough to be read.
- Turn on denial alerting for blocked egress and out-of-scope tool calls, and run one tabletop exercise against a hypothetical successful injection — credential revocation, blast-radius reconstruction, notification.
Nothing here makes prompt injection go away. Done together, they change the worst realistic outcome from ‘attacker used our agent’s credentials against our data’ to ‘attacker wasted a run and we have the logs’. That is the achievable goal, and teams that aim at it ship faster than teams still waiting for the fix.
Frequently asked questions
Can prompt injection be fixed?
Not with current architectures. A language model receives one undifferentiated token stream, and nothing in it reliably marks which parts are operator instructions and which are data. Delimiters and system prompts only shift probabilities, so the practical goal is containment: making a successful injection bounded, logged and recoverable.
What is the single most effective defence for AI agents?
Egress control. Most damaging injection chains end in exfiltration, so an allowlist of destinations enforced at the network or proxy layer, rather than in the prompt, breaks the final hop regardless of what the model was persuaded to do. It should also cover client-side fetches triggered by rendered output.
Why are injection classifiers not enough?
The input space is unbounded natural language, and attackers iterate against a filter for free while defenders update once per release. A detector strict enough to catch the tail rejects legitimate documents. Classifiers are useful as a rate limiter and a telemetry source, but not as a control boundary.
When does human confirmation actually work?
When the prompt shows the concrete effect, such as recipient, amount, file paths or records affected, rather than the model’s description, and when it is reserved for irreversible actions so approvals stay rare enough to be read. Staged writes, drafts and soft deletes reduce how often confirmation is needed.
Sources and further reading
- OWASP Gen AI Security Project — LLM01:2025 Prompt Injection
- NIST AI 100-2 E2025 — Adversarial Machine Learning: A Taxonomy and Terminology of Attacks and Mitigations
- Greshake et al., Not what you’ve signed up for: Compromising Real-World LLM-Integrated Applications with Indirect Prompt Injection (arXiv:2302.12173)
- Design Patterns for Securing LLM Agents against Prompt Injections (arXiv:2506.08837)
- UK NCSC — Principles for the security of machine learning
How this article was produced
This article was researched, written and fact-checked by the Editorial Team and edited to the techstrendery.com editorial standards described on our About us page. Figures described as illustrative are exactly that and are labelled in the text. More reporting on this beat is collected under Cybersecurity. If you find an error, tell us through the contact page; corrections are published in place with a dated note.
Written by
Editorial Team
Every TechsTrendery article is researched, tested and fact-checked by the Editorial Team before it is published, and corrected in public when something changes. Read how we work.

