Prompt injection is the SQL injection of agents. The root cause is the same: trusted instructions and untrusted data get concatenated into one string, and the interpreter can't tell them apart.
SQL injection got fixed with parameterized queries. Agents have no equivalent guarantee yet. OWASP's own guidance says it's unclear whether fool-proof prevention exists. So you design for containment.
How we handle it:
1. Anything that didn't come from the user or the system is data. Web pages, tool outputs, emails, file contents, API responses, messages from other agents. All of it is untrusted.
2. Fence it. Wrap external content in explicit markers that record where it came from, and tell the model nothing inside the fence is an instruction. This lowers the risk, but on its own it is not a security boundary.
3. Enforce in code, not in prose. The harness decides which tools can be called once untrusted content is in context. Google DeepMind's CaMeL research (2025) goes further: a planner that never sees untrusted data, a quarantined model that parses it, and capability checks on every tool call.
4. Watch the sinks. Exfiltration happens through outbound channels: email, messages, URLs with query strings, rendered markdown images. Lock those down first.
5. Human confirmation on sends. Any message, post, payment, or share that leaves the system shows a person the exact content before it goes.
If a web page can tell your agent to email your CRM export to a stranger, you don't have an agent. You have an open relay with a nice UI.