Markdown rendering is enabled for AI response surfaces
Why it matters
When AI response text is injected directly into the DOM via plain string interpolation, every **bold**, ## heading, and `code block` in the model's output renders as raw punctuation — a UX failure that signals a half-finished integration. Worse, some models emit markdown-formatted content specifically because they are prompted or fine-tuned to do so; stripping rendering creates a mismatch between what the model produces and what the user sees. OWASP LLM05 identifies trust and safety failures in output presentation as a category of harm; showing raw syntax characters where formatted prose was intended degrades user trust and undermines the inference-contract between model and interface.
Severity rationale
Critical because raw markdown syntax in a user-facing interface is both a visible defect and a signal that the AI integration was never tested end-to-end with real model output.
Remediation
Install react-markdown with GFM support and replace any plain string interpolation of AI output:
import ReactMarkdown from 'react-markdown'
import remarkGfm from 'remark-gfm'
// Replace: <p>{message.content}</p>
<ReactMarkdown remarkPlugins={[remarkGfm]}>
{message.content}
</ReactMarkdown>
For streaming responses, wrap in a component that buffers partial tokens before passing them to the renderer to avoid mid-token syntax artifacts.
Detection
-
ID:
markdown-rendering-enabled -
Severity:
critical -
What to look for: Enumerate all relevant files and Find all components that render AI-generated text. Check whether they use a markdown rendering library (react-markdown, marked, remark, rehype, mdx, etc.) or render raw text via plain string interpolation (which would expose raw
**bold**and##syntax to users). Check whether plain<p>tags or basic{response}interpolation is used without markdown processing. Quote the exact code pattern or configuration value found. -
Pass criteria: At least 1 conforming pattern must exist. All AI response surfaces use a markdown rendering library or a purpose-built prose renderer. Headings, bold, italics, lists, and code blocks in AI output are rendered as formatted HTML, not shown as raw syntax characters.
-
Fail criteria: AI response text is rendered directly as plain text or via simple string interpolation without markdown processing, causing raw syntax characters to appear in the UI for users. A partial or incomplete implementation does not count as pass.
-
Skip (N/A) when: No AI SDK or AI API client is detected in
package.jsondependencies (openai, @anthropic-ai/sdk, ai, langchain, cohere-ai, etc.). -
Cross-reference: For security evaluation of AI prompt handling and injection prevention, the AI Prompt Injection audit covers input sanitization and system prompt protection.
-
Detail on fail:
"AI response rendered via {message.content} with no markdown library in ChatMessage.tsx — users see raw '**bold**' syntax"(max 500 chars) -
Remediation: Install and wire in
react-markdown(or equivalent) to process AI output before rendering:npm install react-markdown remark-gfmimport ReactMarkdown from 'react-markdown' import remarkGfm from 'remark-gfm' // Before — raw text <p>{message.content}</p> // After — properly rendered markdown <ReactMarkdown remarkPlugins={[remarkGfm]}> {message.content} </ReactMarkdown>For streaming responses, ensure the markdown renderer handles partial content gracefully. The AI Chat Visibility Audit covers streaming UI patterns in more depth.
External references
- owasp-llm:2025 · LLM05 — Improper Output Handling
Taxons
History
- 2026-04-18·v1.0.0·Initial import from ai-response-quality·automated