Security · ~7 min
Fourteen lessons defended the way in — what the agent reads. This is the way out: what the agent writes, executed or rendered downstream without anyone checking. Same trust failure, opposite direction.
Trust does not transfer through a string boundary. Your input-validation layer checked the user prompt, not the model response — so when that response reaches a code-interpreting sink, the system meets text nothing in the pipeline ever scrutinised. Treat agent output as untrusted input to the next system.
OWASP LLM05:2025 Improper Output Handling is "insufficient validation, sanitization, and handling of the outputs generated by large language models before they are passed downstream." Its rule is one sentence: treat the model as any other user and apply input validation to its responses. The five canonical sinks:
| Sink | Risk | Per-sink control |
|---|---|---|
exec/eval/shell | Remote code execution | Command allowlist; never eval a model string |
| Unparameterised SQL | SQL injection | Prepared statements — never interpolation |
| Browser-rendered HTML/markdown | XSS, image exfiltration | Context-aware encoding; CSP; fetch gating |
| Unsanitised file paths | Path traversal | Canonicalise, constrain to a base dir |
| Package manager | Slopsquatting install | Resolve against an installed lockfile first |
The canonical instantiation is CVE-2025-1793 in LlamaIndex (CVSS 9.8): vector-store integrations built SQL by string-concatenating an LLM-generated query, fixed in 0.12.28 by switching to parameterised queries. The fix isn't LLM-specific — it's the same parameterisation that defends any user-supplied SQL string.
The model never writes SQL; a deterministic executor builds the parameterised query from validated fields. Schema- constrained tool calling makes the schema the validator.
This is not Lesson 8's blast radius. OWASP draws the line: LLM06 Excessive Agency is the agent taking action (too much functionality, permission, autonomy); LLM05 is a downstream consumer mishandling the text the agent produced. A perfectly permission-bounded agent can still trigger LLM05 if its bounded actions emit strings consumed unsafely. Defend both — independently.
Per-sink validation is not free, and four conditions invert it. Mature teams that already parameterise every query and escape every render gain nothing from a parallel LLM-specific scanner — confirm, don't duplicate. An agent that drafts emails for human review or writes code a developer reads before commit has no code-interpreting sink in that path. Stream-level "strip URLs / strip code" sanitisers reject legitimate docs and samples — prefer escaping at the sink over stripping the stream. And strict structured outputs already constrain the model to schema-conformant fields.
Retrieval practice — recall, don't peek
Question 1OWASP LLM05 Improper Output Handling is about…
Question 2The reason output handling fails is that trust…
Question 3The per-sink controls for LLM05 are best described as…
Question 4The right fix for the CVE-2025-1793 SQL class is to…
Question 5 · spaced recall from Lesson 14In a URL-exfiltration attack, the private data leaks…