Join our Newsletter — 33% off our NHI Course
Home› Guides› OWASP LLM Top 10 LLM05 Improper Output Handling…
Guide LLM & GenAI Security

OWASP LLM Top 10 LLM05 Improper Output Handling Guide: Treating Model Output as Untrusted

PDF for newsletter subscribers · free to read online

← All guides
By NHI Mgmt Group, edited by Lalit Choda Updated 26 October 2026 14 min read
On this page

Applications that pass large language model output straight into a browser, a database, a shell or another API are handing every person who can influence the prompt a route into those systems. LLM05:2025 Improper Output Handling is the OWASP Top 10 for LLM Applications entry for this failure: insufficient validation, sanitisation and handling of model output before it reaches downstream components. This guide goes deeper than the overview page. It covers the sink-by-sink controls, the identity of the components that consume output, a phased rollout, how to test and evidence the controls, and how LLM05 maps to ASVS 5.0, NIST SP 800-53 and MITRE ATLAS. It is written for application security engineers, developers building LLM features and the reviewers who sign them off.

Key takeaways

  • Model output is untrusted input. OWASP's first mitigation is to treat the model "as any other user" and validate its responses before they reach backend functions, because anyone who shapes the prompt, directly or through retrieved content, shapes the output.
  • The damage is classic web and injection bugs. OWASP lists XSS, CSRF, SSRF, privilege escalation and remote code execution as the results, so the fixes are the ones you already know: context-aware encoding, parameterised queries, allowlists and no eval.
  • Markdown rendering is an exfiltration channel. EchoLeak and ForcedLeak both moved data out by getting an image URL into rendered output, so Markdown and image handling deserve as much attention as script tags.
  • Privilege multiplies impact. The same unvalidated output is a nuisance in a read-only chat window and a breach when the consuming component runs with a powerful database or cloud identity.
  • Prove it with tests, not prompts. System prompt instructions such as "never output HTML" are not a control; unit tests that push hostile markup, SQL and path strings through every output sink are.

What it is and who it applies to

OWASP defines Improper Output Handling as "insufficient validation, sanitization, and handling of the outputs generated by large language models before they are passed downstream to other components and systems". Because model output can be controlled through prompt input, OWASP describes the effect as "similar to providing users indirect access to additional functionality". In the 2023/24 edition the same risk was LLM02 Insecure Output Handling.

OWASP separates LLM05 from neighbouring entries, and the distinction matters for ownership:

EntryQuestion it asksTypical owner
LLM01 Prompt InjectionCan someone change what the model is trying to do?AI platform and application team
LLM05 Improper Output HandlingIs whatever the model produced safe for the component that consumes it?Application developers, AppSec
LLM06 Excessive AgencyWhat can the system do with that output, and with whose permissions?Architects, IAM, platform owners
LLM09 MisinformationIs the content accurate enough to rely on?Product owners, users

LLM05 applies to any system where generated text becomes code, markup, a query, a file path, a URL, a template or a command. That includes chat interfaces that render Markdown, text-to-SQL and analytics assistants, code assistants, email and document generators, agents that pass one model's output to a tool or to another model, and retrieval pipelines that summarise external web pages. Prompt injection is the usual trigger, but OWASP's framing does not depend on an attacker: a hallucinated query that drops a table is still an output handling failure. See the OWASP Top 10 for LLM Applications Guide for the whole list and the Prompt Injection Guide for the input side.

Structure and key requirements

OWASP gives five common examples, six aggravating conditions and seven mitigations. The practical way to apply them is per sink: for each place model output lands, decide the encoding, validation and privilege rule.

SinkFailure OWASP describesPrimary controlASVS 5.0 requirement
Browser (HTML, JavaScript)Generated JavaScript or Markdown interpreted by the browser, giving XSSContext-aware output encoding; sanitise any HTML with a maintained library; strict CSPV1.2.1, V1.3.1, V3.4.3
Markdown rendererImages and links that fetch attacker URLs carrying dataDisable or sanitise scriptable Markdown; allowlist image hosts; strip reference-style linksV1.3.5
DatabaseGenerated SQL executed without parameterisationParameterised queries; a read-only, narrowly scoped database identity; query allowlists for text-to-SQLV1.2.4
Shell, exec, evalOutput entered into a system shell, exec or eval, giving RCENever execute output directly; parameterised OS calls; sandbox where code execution is the featureV1.2.5, V1.3.2
File systemOutput used to build file paths, giving path traversalCanonicalise and check against a base directory; map output to IDs not pathsV1.3.3
Outbound HTTPOutput used as a URL, giving SSRF or data exfiltrationAllowlist of protocols, domains and ports; egress proxyV1.3.6
Email and templatesOutput placed in email templates without escaping, enabling phishing or XSSEscape per template context; never build templates from output; sanitise for SMTPV1.3.7, V1.3.11
Another model or toolOutput passed to a privileged extension without validationSchema validation of structured output; quarantine untrusted contentV1.3.3

The aggravating conditions OWASP lists are worth turning into review questions: does the application grant the LLM privileges beyond those of end users, is it exposed to indirect prompt injection, do third-party extensions validate their inputs, is encoding applied per context (HTML, JavaScript, SQL), are outputs logged and monitored, and is there rate limiting or anomaly detection on LLM use?

Real cases that show the pattern

  • Code execution: CVE-2023-29374 affected LangChain through 0.0.131; NVD records that the LLMMathChain chain allowed prompt injection to execute arbitrary code through Python's exec method (CVSS 3.1 9.8, CWE-74). CVE-2024-5565 in the Vanna library is similar: with visualize set to True, the default, prompt injection could make the generated visualisation code run arbitrary Python (CWE-94).
  • Rendered image exfiltration: in the EchoLeak Microsoft 365 Copilot case (CVE-2025-32711), reference-style Markdown images survived Copilot's link filtering and trusted Microsoft services were used to get past its Content Security Policy. In ForcedLeak, Agentforce output placed CRM data in an image URL on an expired domain that was still on the CSP allowlist.
  • Cross-tool forgery: in May 2023 Embrace The Red showed ChatGPT URL-encoding an email summary obtained through one plugin and loading an attacker URL with a browsing plugin. Output from one step was trusted as an instruction by the next.

Identity and NHI requirements

Output handling is usually discussed as an encoding problem, but the impact is set by the identity of whatever consumes the output. OWASP's first aggravating condition is an application that "grants the LLM privileges beyond what is intended for end users". In practice that privilege sits in a non-human identity: the database login used by a text-to-SQL feature, the cloud role of the code-execution sandbox, the API key a summariser uses to fetch URLs, or the OAuth token an email generator sends with.

  • One identity per output sink: give the SQL executor, the code sandbox and the fetcher separate service identities so a weakness in one sink cannot use another sink's rights. See the Service Account Security Guide.
  • Least privilege on the consumer: a reporting assistant's database identity needs SELECT on named views, not the schema owner. A dropped table from a generated query (OWASP scenario 3) is impossible if the login cannot DROP. See the OWASP NHI Top 10 NHI5 Overprivileged NHI Guide.
  • User context where data is personal: when output drives a query on behalf of a signed-in user, run it with that user's delegated token or row-level security, so the model cannot return rows the user could not see.
  • No secrets in the execution environment: code interpreters and sandboxes should start with no ambient credentials, no metadata service access and no mounted keys. See the AI Agent Sandboxing and Code Execution Guide.
  • Egress identity: outbound fetches should leave through a proxy that authenticates the calling workload and enforces a domain allowlist, which is also the control that would have stopped the image-based exfiltration above.

Implementation steps

  1. Inventory sinks (weeks 1-2): trace every code path where model output, including tool results and retrieved content echoed by the model, is rendered, executed, stored, queried or sent. Record the sink type, the identity it runs as and the user population that can reach it.
  2. Remove the worst sinks first: delete any direct exec, eval, shell or raw SQL execution of output. Where code execution is the feature, move it into an isolated sandbox with no network by default and no credentials.
  3. Constrain output shape: where the application expects data rather than prose, require structured output (JSON with a schema) and reject anything that does not validate. For text-to-SQL, validate generated statements against an allowlist of statement types, tables and columns before execution, and bind values as parameters.
  4. Encode at the point of use: HTML-encode in HTML bodies, attribute-encode in attributes, JavaScript-encode in scripts, and never insert output into templates as template source. Use a maintained HTML sanitiser where rich text is required.
  5. Lock down Markdown and images: render Markdown with raw HTML disabled, strip or rewrite image and link URLs to an allowlist, block reference-style link definitions you do not need, and consider showing links as text until the user clicks.
  6. Set CSP and egress controls: deploy a strict Content Security Policy for LLM-rendered pages (tight img-src and connect-src), review the allowlist for expired or third-party-controlled domains, and route server-side fetches through an egress proxy.
  7. Quarantine untrusted content: where a model processes emails, web pages or documents, keep that output away from components that can act. Simon Willison's Dual LLM pattern passes untrusted results by reference ($VAR1) so the privileged model never reads them; its author notes it is not fully reliable, so pair it with the controls above.
  8. Test in report-only first, then enforce: run CSP in Content-Security-Policy-Report-Only, run new output validators in log-only mode against production traffic for one to two weeks, review false positives, then switch to blocking. Keep the previous renderer behind a feature flag for rollback.
  9. Add regression tests to CI: fixed test cases that make the model, or a stub of it, return script tags, Markdown images to external hosts, SQL with stacked statements, ../ paths and internal URLs, and assert each sink encodes or rejects them.

Choosing a control by sink

SituationPreferTrade-off
Output only shown to the same userPlain-text rendering or sanitised Markdown with no external imagesLoses rich formatting; lowest risk
Output shown to other users (shared chats, tickets, emails)Full sanitisation plus CSP; treat as stored XSS riskMore engineering; mandatory because victims did not write the prompt
Text-to-SQL for analystsRead-only replica, allowlisted views, statement validationSome questions cannot be answered; safer than free SQL on primary
Code generation that is executedEphemeral sandbox, no secrets, no default networkLatency and cost; the only defensible option for executing output
Small team, one LLM featurePlain text, no tools, a hosted model with built-in output filters as a second layerLess flexible; fewer sinks to secure

Evidence and assessment

OWASP's last mitigation is "robust logging and monitoring systems to detect unusual patterns in LLM outputs". Assessors should expect to see both the preventive controls and the telemetry.

  • Design evidence: the sink inventory, the identity each sink runs as, and the encoding or validation rule per sink.
  • Test evidence: CI results for the hostile-output regression suite, SAST rules that flag model output flowing into exec, eval, subprocess, raw SQL or template engines, and DAST or manual test reports against rendered output.
  • Runtime evidence: CSP violation reports, blocked egress requests, schema validation failures and sanitiser removals, logged with session and user identifiers.
MetricWhat good looks like
Sinks with a documented and tested control100 percent of inventoried sinks
Direct exec, eval or raw SQL calls on model output in codeZero, enforced by SAST in the pipeline
CSP violation reports from LLM-rendered pagesTrended weekly; every new external host investigated
Structured output validation failure rateBaselined; sudden rises reviewed as possible injection
Egress requests from LLM components to non-allowlisted hostsZero allowed; all blocked attempts reviewed
Output sink identities with write or admin rights not justified in reviewZero

Mapping to other frameworks

FrameworkReferenceRelevance to LLM05
OWASP ASVS 5.0V1.2.1, V1.2.4, V1.2.5, V1.3.2, V1.3.5, V1.3.6, V1.3.7, V3.4.3Context encoding, parameterised queries and OS calls, no eval, Markdown sanitisation, SSRF allowlists, template injection, CSP
NIST SP 800-53 Rev. 5SI-10 Information Input Validation; SI-15 Information Output FilteringValidate output as input to the next component; filter output for anomalous content
NIST SP 800-53 Rev. 5AC-4 Information Flow Enforcement; SC-18 Mobile CodeEgress and image URL control; control of generated script content
NIST SP 800-53 Rev. 5SA-11 Developer Testing and Evaluation; AU-12, SI-4Hostile-output test suites; logging and monitoring of output
NIST CSF 2.0PR.PS-06; DE.CM-09Secure development practice; monitoring software and runtime for adverse events
MITRE ATLASAML.T0051 LLM Prompt Injection; AML.T0077 LLM Response Rendering; AML.T0067 LLM Trusted Output Components ManipulationThe trigger, the rendering exfiltration path, and manipulation of output users trust
MITRE ATLASAML.T0086 Exfiltration via AI Agent Tool InvocationWhere output becomes a tool call that sends data out
OWASP Agentic Top 10ASI05 Unexpected Code Execution (RCE)The agentic form of executing generated code
ISO/IEC 27001:2022 Annex AA.8.26 Application security requirements; A.8.28 Secure codingWhere output handling rules and encoding standards are required

See the OWASP ASVS Guide, the Cross-Site Scripting (XSS) Prevention Guide, the SQL Injection Prevention Guide and the SSRF Prevention Guide for the underlying controls, and the OWASP Agentic Top 10 ASI05 Guide for agents that execute code.

Common pitfalls

  • Trusting the system prompt: instructing the model not to emit HTML or SQL keywords. Injected content overrides instructions; only code at the sink enforces anything.
  • Filtering links but not images: stripping inline links while reference-style images, auto-loading previews or allowlisted proxies remain, which is exactly the gap EchoLeak used.
  • A stale CSP allowlist: listing third-party or expired domains in img-src. ForcedLeak's channel was an allowlisted domain anyone could buy for about five dollars.
  • Executing "helpful" code: math, chart and data-analysis features that run generated Python in the application process, as in the LangChain and Vanna CVEs.
  • A powerful identity behind text-to-SQL: connecting the query executor as the schema owner, so a hallucinated or injected DELETE succeeds.
  • Treating internal consumers as safe: passing output to an internal admin API or another model without validation because "it is not user-facing", which is OWASP's first attack scenario.

Practitioner checklist

  • Maintain an inventory of every sink that consumes model output, with the identity each runs as.
  • Remove all direct exec, eval, shell and raw SQL use of model output, and block reintroduction with SAST rules.
  • Require schema-validated structured output wherever the application expects data.
  • Apply context-aware encoding at every render point and a maintained sanitiser for rich text.
  • Render Markdown with raw HTML off and image and link hosts restricted to an allowlist.
  • Deploy a strict CSP on LLM-rendered pages and review its allowlist for third-party or expired domains quarterly.
  • Run generated code only in a credential-free, network-restricted sandbox.
  • Give each sink a least-privilege service identity, read-only where possible.
  • Keep a hostile-output regression suite in CI and roll out new validators in report-only mode first.
  • Log output validation failures, CSP violations and blocked egress with session identifiers, and alert on spikes.

Standards and references

Related NHI Mgmt Group resources: OWASP Top 10 for LLM Applications Guide · OWASP LLM Top 10 LLM06 Excessive Agency Guide · Prompt Injection Guide · Content Security Policy Guide · LLM Security Guide

PDF for subscribers

Take this guide with you

Every section, table and checklist in one PDF, with links to the sources and related guides. Subscribe to our weekly NHI & AI Identity Journal and we’ll email you a download link.

Free weekly newsletter

Subscribe to the NHI & AI Identity Journal

The latest on NHI and Agentic AI security – articles, research, breaches, news and events every week.

Bonus 33% off our NHI Course when you subscribe.

NHIMG Editorial Note
Researched and written by the NHI Mgmt Group editorial team using AI tools, under the editorial direction of Lalit Choda. Facts are drawn from the sources listed on this page and checked by our automated quality process. Last updated 26 October 2026. Spotted an error? Use our contact page.
NHI Mgmt Group, the independent authority on Non-Human Identity, IAM and Agentic AI security. nhimg.org

PDF Downloads for Newsletter Subscribers

Get the guide

Enter your details and we’ll email you a download link.

The full guide is free to read online. The PDF is a thank you for subscribing.

Fill in all fields marked * and tick the PDF box to continue.