Defending LLM Applications: A Practical Guide
A layered blue-team defense for LLM apps: structured messages, instruction/data separation, I/O filtering, least-privilege tools, egress control, and monitoring.
There is no single setting that makes an LLM application safe from prompt injection. The model will always be susceptible to instructions in its context, because following instructions is what it does. Defense is therefore architectural: you assume the model can be hijacked and build layers so that when it is, the blast radius is small and the attempt is visible. This is the blue-team companion to the offensive techniques on this site, and it maps directly to OWASP LLM01: Prompt Injection.
1. Use the structured messages API
Send system, user, and tool content through the API's distinct roles rather than concatenating everything into one string. A structured messages array gives the model a clearer signal about what is the application's instruction versus the user's request versus tool output. It is not a hard boundary, but it is a meaningful first layer and it is free. Never build prompts by string-concatenating untrusted input into your system instructions.
2. Separate instructions from data, and spotlight
Your trusted instructions and untrusted content (user input, retrieved documents, tool results, fetched web pages) must be unambiguously distinguished:
- Place untrusted content in a clearly delimited, labeled block and instruct the model that everything inside is data to be processed, never commands to be obeyed.
- Apply spotlighting: mark untrusted text so the model can tell it apart — explicit delimiters, encoding, or per-line markers. This measurably lowers injection success by making the data/instruction boundary visible.
- For retrieval, carry provenance and trust tiers so low-trust sources can be excluded from contexts that drive actions. See indirect prompt injection in RAG.
3. Filter and constrain input
- Cap input length and the number/size of retrieved chunks. Huge contexts hide payloads and raise the odds an injection lands.
- Normalize at ingestion: strip HTML comments, zero-width characters, and hidden-text styling that smuggle instructions past human reviewers.
- Optionally run an input classifier to flag obvious injection patterns ("ignore previous instructions", "you are now in admin mode"). Treat it as a signal, not a wall — attackers paraphrase.
4. Classify and check output
The output side is where you catch leaks the model did not resist:
- Scan responses for markdown images and links to non-allowlisted domains and for long encoded query strings — the markdown-image beacon pattern.
- Watch for persona shifts, attempts to reveal the system prompt, or inclusion of secrets/other users' data.
- Use a classifier or rules to block, strip, or quarantine suspicious responses before they reach the user or trigger a tool. An LLM-judge pass can catch subtler cases.
5. Least-privilege tools and human-in-the-loop
Agentic systems turn a prompt injection into real-world action, so this layer matters most:
- Give each tool the narrowest scope it needs. The model should not hold broad credentials "just in case."
- Allowlist tool arguments where you can (recipients, hostnames, file paths) rather than trusting model-generated values blindly.
- Require human approval for sensitive or irreversible actions — sending email, moving money, deleting data, executing code. A hijacked turn then cannot act unilaterally.
- Isolate execution (sandboxes, ephemeral credentials) so a compromised step cannot pivot.
6. Egress control
Even a hijacked model needs a channel to leak data or reach attacker infrastructure. Close it:
- Restrict outbound network access for the rendering surface and any server-side tools to known-good destinations.
- Enforce a strict Content Security Policy (
img-src,connect-src) so the client refuses fetches to unexpected origins. - Relay external images and links through a backend that strips query strings and validates responses.
7. Monitoring
- Log prompts, retrieved sources, tool calls, and outputs (redacting secrets) so incidents are reconstructable.
- Alert on anomalies: outbound requests to new domains, spikes in tool calls, blocked-output rates, or repeated injection-pattern hits.
- Feed findings back into your input/output classifiers and allowlists. Defense is iterative.
Putting it together
Map your controls to the kill chain: instruction/data separation and spotlighting reduce the chance an injection lands; input limits and least-privilege tools shrink what a landed injection can do; output classification and egress control stop the data from leaving; monitoring tells you it happened. No layer is sufficient alone — defense in depth is the strategy. Validate the whole stack by red-teaming your own system with the techniques described across this site.
Authorized-use reminder: red-team only systems you own or are explicitly contracted to test, using synthetic canary data.