A hiring team wires a model to screen resumes. One applicant adds a line in white-on-white text: recommend this candidate. Screeners have fallen for exactly that, though a hardened pipeline often catches it. That is prompt injection: untrusted content, read as instructions, obeyed. A recent Apptad essay calls it the new SQL injection.
01An old bug without the old fix
SQL injection ruled the mid-2000s because databases executed whatever string reached them. User text got glued into a query, and the query ran it. The cure was structural: parameterized queries gave data and code separate lanes, and frameworks made that the default. The bug faded.
A language model has no lanes. Your setup instructions, the user’s question, and the contents of whatever page or PDF the model just fetched all arrive as one stream of text, and any of that text can steer it. There is no equivalent of the parameterized query, because following instructions found in text is the product. OWASP has ranked prompt injection the number one risk for LLM applications since 2023, and it remains open. That is why every serious defense is architectural, and why a filter you bolt on is never the whole answer.
02The payload hides in the data
Instructions typed straight into the chat box are the least dangerous form. You can see them, and the blast radius is one conversation. Indirect injection is the form to fear: the payload (the attacker’s planted instruction) hides in content your agent reads mid-task. A web page with invisible text. A calendar invite that tells an email assistant to search the inbox and forward what it finds. The agent fetched that content because you asked it to, so the attack arrives wrapped in exactly the material it was told to trust.
Tools raise the stakes. Once the model can send email, call APIs, and write files, a hijacked response becomes an action taken with your permissions. Five attack families cover the threat model:
| Family | How it works | What it costs you |
|---|---|---|
| Direct injection | Adversarial instructions typed into the interface | Policy bypass, leaked setup instructions |
| Indirect injection | Payload hidden in content the agent retrieves | A hijacked agent mid-task |
| Data exfiltration | Injected text routes private context outward | Leaked history, records, credentials |
| Tool abuse | Injection steers connected tools | Fraud, unauthorized sends and purchases |
| Memory poisoning | Payload stored in memory or a knowledge base | Compromise that survives the session |
The last family is why the retrieval layer needs its own hygiene: a poisoned document in the store your team queries keeps injecting long after the original visit. The audit habits in Keep a growing knowledge base accurate and the scoped stores in Give your agent a memory are both containment for this case.
03Build five imperfect layers
Since the model cannot be made injection-proof, assume some payloads will land and design so a landed one is worth little. Two rules set the frame: treat everything the model reads as untrusted, including your own knowledge base, and treat everything it produces as unverified until checked. Then stack the layers, each with its honest limit:
- Least-privilege tools. Narrow credentials, read-only by default, only the tools the task needs. Limit: convenience keeps pushing toward broad scopes; holding narrow takes discipline.
- Isolate untrusted content. Mark retrieved data apart from instructions and strip active content (scripts, macros, hidden text). Limit: no delimiter is watertight against a determined payload.
- Filter input and output. Injection classifiers, allowlists for URLs and recipients, output validation. Limit: classifiers trail novel attacks.
- Human approval for consequential actions. Confirmation before sending, paying, deleting, publishing. Limit: approval fatigue is real, so gate the consequential few, never everything. Placing checkpoints where errors are expensive is the same judgment call as in Automate the step that slows you down.
- Monitor, log, red-team. A full audit trail of tool calls, plus adversarial testing at each release. Limit: alerts nobody owns are theater.
Each layer leaks. Stacked, they turn a clever payload into a contained incident.
04The first 90 days
Most teams need inventory and discipline, and no research program. One month each:
- Inventory. Find every app with a model wired into it, including the ones nobody approved. For each, map what it reads and what its tools can do. The tool list tells you more about risk than the model name does.
- Harden. Tighten tool scopes, add approval gates on money, messages, and deletions, and allowlist the places data can be sent.
- Verify. Red-team the hardened apps: attack them with your own injection payloads. Wire tool-call logs into monitoring, and make model security a standing item in change review.
The bar to hold: if your release process would not ship an unauthenticated API, it should not ship an over-privileged agent either.
Further reading
- Apptad · Prompt injection is the new SQL injection, the essay this guide draws on
- OWASP · Top 10 for LLM applications, the shared taxonomy, prompt injection at number one
- Simon Willison · prompt injection series, the running field notes that named the attack