A chatbot that can only talk has a limited blast radius. An agent that can read your email, query your CRM and send messages does not. That is why prompt injection is widely treated as the leading security risk for LLM applications: it appears at the top of the OWASP list of risks for LLM applications, and it gets more dangerous every time you give an agent another tool.
What is prompt injection?
Language models receive instructions and data in the same channel: text. They have no reliable, built-in way to tell "this is a command from my operator" apart from "this is text I happened to read". Prompt injection exploits that: an attacker plants instructions where the model will read them, hoping it obeys.
- Direct injection: the user types something like "ignore your previous instructions and...". Often called jailbreaking.
- Indirect injection: the malicious text hides in content the agent retrieves: a web page, an email, a PDF, a support ticket, a code comment, or the output of a tool. The user never sees it. This is the more serious threat for agents.
What can go wrong?
- Data exfiltration: the agent is tricked into sending private data to an attacker, for example via a link, an image URL or an outbound message.
- Unauthorised actions: issuing refunds, changing records, forwarding emails, running code.
- Tool and server poisoning: a malicious or compromised tool description or MCP server steers the model.
- Cross-agent spread: a compromised output infects other agents in a multi-agent system.
The dangerous combination
Security researchers describe a "lethal trifecta": an agent is at serious risk when it combines access to private data, exposure to untrusted content, and the ability to communicate externally. With all three, one planted instruction can read secrets and send them out. The most reliable fix is to design so that no single agent has all three at once.
Private data
CRM, email, documents
Untrusted content
Web, inbound email, uploads
External actions
Send, post, call APIs
Risk
All three together = exfiltration path
Why you cannot just "tell the model not to"
System-prompt warnings and input filters help, but they are probabilistic defences against a creative, adaptive adversary. Treat them as one layer, never the only one. The sound security posture is to assume the model will sometimes be fooled and limit what happens when it is.
A layered defence
1. Least privilege
Give each agent the narrowest credentials and tools for its job. Prefer read-only. Run actions with the end user's permissions, not a shared super-account.
2. Break the trifecta
Separate agents that read untrusted content from agents that hold sensitive data or can act. Pass between them only structured, validated data, not free text that may contain instructions.
3. Human approval for consequential actions
Require confirmation before sending messages, moving money, deleting data or changing permissions, and show the human exactly what will happen.
4. Control the exits
Restrict outbound network access with allowlists, strip or block auto-loading of remote images and links in agent output, and monitor for unusual data leaving.
5. Treat tool output as untrusted
Label retrieved content as data, validate it against schemas, and never let it silently expand the agent's permissions or tool list.
6. Sandbox and isolate
Run code and browsing in isolated environments with no standing access to secrets.
7. Test, monitor and log
Red-team with injection attempts, include them in your evaluation suite, trace every tool call, and alert on anomalies.
Where to start
- List every tool and data source each agent can reach. Remove what it does not need.
- Find any agent that has all three trifecta ingredients, and split it.
- Add approval gates to every irreversible action.
- Add injection cases to your tests before launch, not after an incident.
We build agents with these controls in the harness from day one. Talk to us about a security review of your AI agents.