Prompt injection and LLM security: assume your model can be socially engineered
Any text your model reads can try to hijack it. Treat retrieved content as data not instructions, give tools least privilege, and design so the blast radius stays small when the model gets fooled.
A language model can't reliably tell your instructions apart from instructions hidden in the content it reads. A web page, a document, an email — any of them can say 'ignore your previous instructions and…', and the model may just comply. That's prompt injection, it isn't fully solved, and so you don't try to prevent it perfectly — you design so it doesn't matter much when it happens.
Retrieved content is data, not commands
The core discipline: content the model ingests — retrieved documents, user messages, tool results — is untrusted data, never trusted instructions. Keep the trusted system prompt clearly separated from untrusted content, and never let something the model read escalate itself into an action. Treating the model as a literal, gullible function (not a colleague with judgement) is the right mental model here.
Least-privilege tools
The damage a successful injection can do is bounded entirely by what the model is allowed to do. Read-only by default, narrowly scoped credentials, and human approval for anything irreversible mean a fooled model simply can't reach the dangerous levers (see the tool-calling post).
Design for a small blast radius
- Assume compromise — build as if the model will be tricked, because eventually it will.
- Limit what one turn can touch — scope actions so a single hijacked turn can't cascade.
- Enforce authorization outside the model — permissions and tenant boundaries live in your code and your database, never in the prompt (see the query-safety post).
- Keep secrets out of context — don't put anything in the prompt you couldn't afford to have exfiltrated.
You won't prevent every injection. So build it so that when one lands, the model simply can't do anything worth the attacker's trouble.