The direct answer

Treat model output as untrusted content at every rendering surface. Prefer plain text, allow only the formatting your interface needs, validate link destinations, and prevent automatic remote resource loads from becoming an unintended disclosure channel.

A good answer can still be unsafe to display

A support assistant returns a useful paragraph followed by a Markdown image. Rendering that image may make a browser request before anyone clicks anything. In another answer, text that resembles HTML may be interpreted as markup if the application puts it into an unsafe rendering sink. Answer quality and display safety are separate acceptance questions.

OWASP identifies insufficient handling of model outputs before downstream use as an application risk, including browser injection. This guide focuses on display paths: chat messages, saved answers, previews and exports. It proposes checks using invented content only. No browser attack, model experiment or security validation has been run for this guide, and the examples describe no vendor vulnerability.

Choose a small rendering contract

Write a contract for one surface before selecting a Markdown plugin. A practical support-draft contract might permit paragraphs, emphasis, lists and code blocks, while excluding raw HTML, embedded frames, forms, scripts, inline styles and automatic remote images. The product owner should explain which user task justifies each additional feature.

For ordinary plain text in a normal page element, OWASP recommends text-safe sinks such as textContent. If rich HTML is intentionally allowed, use a maintained sanitizer with a deliberate allowlist and check the final rendering pipeline. HTML, JavaScript, CSS and URL contexts need different controls. A generic escaping function is not a complete policy for all of them.

Map every transformation: stored answer, Markdown conversion, HTML sanitization, syntax highlighting and final DOM insertion. Check whether a later plugin modifies previously sanitized content. Keep library versions and the rendering configuration in the change record so a successful check applies to an identifiable build.

Copy a five-case synthetic fixture

The following fixture defines expected behavior for the proposed support-draft contract. These strings are display test data. The reserved .invalid destination is intentionally unusable; do not substitute a real recipient or send a network request to prove the point.

[
  {"id":"plain","output":"Order DEMO-17 is ready.","expect":"visible text"},
  {"id":"markup","output":"<b>DEMO-17</b>","expect":"literal text; no raw HTML"},
  {"id":"script-link","output":"[Open](javascript:alert('DEMO'))","expect":"no active link"},
  {"id":"image","output":"![preview](https://display-check.invalid/pixel?case=DEMO-17)","expect":"no image request"},
  {"id":"code","output":"`<b>DEMO-17</b>`","expect":"visible code; no markup execution"}
]

Add a positive formatting case to show that a normal list remains readable. A renderer that makes every answer blank might stop dangerous markup while failing the user task. The reviewer should inspect visible text, the resulting DOM and recorded attempted resource loads, rather than grade a screenshot alone. Use a controlled test harness that intercepts requests; the intended assertion is zero external dispatch.

Keep expected outcomes separate from observed outcomes. This fixture has not been run. Once implemented, record the renderer build, browser, configuration, case identifier and result. Avoid storing a real conversation just to reproduce a formatting failure.

Treat links and images as different actions

A link label can be misleading even when its markup contains no executable code. Parse the destination, apply the application's permitted schemes and destinations, and make the actual destination available to the user. For a support draft, allowing ordinary HTTPS links may be appropriate; a privileged internal console may need a narrower set. Do not rely on a displayed hostname substring to establish the URL's destination.

Images need a separate decision because loading can be automatic. MDN documents that CSP img-src restricts permitted image sources. A policy that excludes remote images can support the display contract, but it is not a complete control for links, scripts or every outbound request. Check the effective application policy rather than copying one header fragment into production.

Referrer-Policy controls the Referer information accompanying requests. A no-referrer policy can omit that header, as MDN explains. It cannot erase sensitive text already embedded in the destination URL itself. Therefore stripping referrer information is not a substitute for preventing a model-generated image URL from carrying conversation data.

Cover streaming, saved views and alternate outputs

Repeat the same acceptance cases through a live message, a reopened saved conversation and an exported preview. A safe chat component does not establish that an administrative transcript viewer uses the same renderer. Include mobile views or notification previews only if the application actually has them, and label unexamined surfaces as unknown.

Streaming adds an intermediate state. Decide whether to buffer until a complete safe fragment is available, or use a renderer designed to maintain the contract throughout incremental updates. In the proposed fixture, split markup and URLs across chunks and assert that no forbidden resource is dispatched at any intermediate step. Checking only the final string can miss a request already sent during rendering.

Rendering failure should produce a readable fallback, such as escaped plain text with a concise formatting notice. Keep the original content restricted if it must be retained for diagnosis; record case identifiers and failure categories in ordinary logs. A new sanitizer or plugin version should trigger the relevant fixture review.

Keep the claim as narrow as the evidence

These checks do not establish that an answer is accurate, nondeceptive or authorized to reveal its text. They address a particular display boundary. Content access, sensitive-data minimization and user decisions about external navigation still require their own controls. Sanitization also depends on configuration and maintained dependencies; avoid claiming that one passing fixture proves universal XSS protection.

Boundary's planned model-request checks do not provide an HTML sanitizer or guarantee browser rendering safety. Its synthetic first-use exercise and eight mock policy checks are separate evidence, not results for this rendering fixture. The next useful result would be an independently inspected run against the actual application renderer, with any remaining surfaces named explicitly.

Primary sources

Official references supporting the guidance. Examples in this guide are synthetic and are not reports of a production incident.

  1. OWASP LLM05: Improper Output Handling
  2. OWASP Cross Site Scripting Prevention Cheat Sheet
  3. MDN Content-Security-Policy img-src
  4. MDN Referrer-Policy header