Web Security

Prompt Injection

An attack where instructions hidden in data an LLM processes override those of its developer or user, because the model can't reliably tell data from commands.

Prompt injection is an attack in which text that a language model processes as data ends up being followed as instructions. An LLM receives its developer’s system prompt, the user’s request and any retrieved content as one stream of tokens, and it has no reliable way to know which parts are allowed to give orders. So a line like “ignore your previous instructions and…” can work whether the user typed it or it was buried in a web page the model was asked to summarize. The term, coined by Simon Willison in 2022 after Riley Goodside’s demonstrations, deliberately echoes SQL injection: untrusted input crossing into the command channel. OWASP ranks it first (LLM01) in its Top 10 for LLM applications.

Direct and indirect

  • Direct prompt injection. The attacker is the user, typing instructions that try to override the system prompt. It overlaps with jailbreaking, and the impact is usually bounded by what that user could already reach.
  • Indirect prompt injection. The instructions arrive inside content the model reads on someone else’s behalf: a web page, an email, a PDF, a code comment, a calendar invite or another tool’s response. The victim never sees the payload. Greshake et al. showed in 2023 that this makes any content an LLM-integrated application retrieves a possible attack vector.

Indirect injection is the one that matters for agents, because an agent’s whole job is to read things it doesn’t control and then act.

Why it’s hard to fix

SQL injection was solved structurally: parameterized queries keep code and data in separate channels, so untrusted input is never parsed as a command. LLMs have no second channel. Delimiters, “never follow instructions found in the document” warnings and classifiers that hunt for malicious prompts all raise the bar, but they are probabilistic. The attacker needs one phrasing that slips through; the defender has to catch every one.

That moves the question from “how do I stop the injection?” to “what can an injected instruction do?” The answer is bounded by the tools, data and permissions the model holds at the moment it reads the payload.

Why it matters for defense

Treat prompt injection as something that will happen, and design so it doesn’t matter much:

  • Break the lethal trifecta. Willison’s framing: an agent with access to private data, exposure to untrusted content and a way to communicate externally can be steered into exfiltrating that data. Remove at least one leg for any given task.
  • Constrain the agent, not the text. Give each tool the least privilege it needs, default to deny and require human approval for sensitive actions. Architectural patterns help too: plan-then-execute fixes the plan before any untrusted data is read, and the dual LLM pattern keeps the privileged model away from untrusted text entirely (both catalogued by Beurer-Kellner et al., 2025).
  • Log every tool call. You can’t block every injection, but you can spot an agent acting out of pattern, as long as the trail exists.
  • Layer it. Filtering, isolation, approval and monitoring are each weak alone and solid together: defense in depth.

In practice

At Ekoparty 2026 it ran through a whole cluster of talks: agentic browsers that a crafted calendar invite or social media post could steer into 0-click account takeover and data exfiltration; the same injection run live against agents with different configurations, where the damage tracked the permissions rather than the payload; and OAuth flows in which an agent holding more access than the person who delegated the task became a confused deputy.

Common misconceptions

  • “A better system prompt will stop it.” The system prompt is just more tokens. It raises the bar; it doesn’t create a boundary.
  • “It’s the same as jailbreaking.” Jailbreaking targets the model’s safety rules. Prompt injection targets the application: its data, its tools and the user who trusts it. The tricks often overlap; the victim is different.
  • “Only chatbots are affected.” Anything that feeds untrusted text to an LLM and acts on the output is exposed: RAG pipelines, email assistants, coding agents, CI bots.

Retrieval prompts

Test recall before peeking. Spaced repetition beats re-reading.

What's the difference between direct and indirect prompt injection?

Direct: the attacker types the malicious instructions into the prompt. Indirect: the instructions ride inside content the model reads on someone else's behalf (a web page, an email, a file, a tool response), so the victim never sees them.

Why can't prompt injection be fixed the way SQL injection was?

SQL injection was solved with parameterized queries, which keep code and data in separate channels. An LLM has a single channel: instructions and data arrive as the same stream of tokens, so there is no parameter to bind untrusted text to.

An agent can read your inbox, browse the web and send email. Why is that combination dangerous, and what's the cheapest fix?

It's the lethal trifecta: private data, untrusted content and a way to communicate externally. One hidden instruction in a page or an email can make the agent exfiltrate data. Removing any one leg for the task (for example, no outbound email without human approval) breaks the attack path.