Long-form descriptions render markdown or HTML correctly; no raw markup shown
Why it matters
Raw markdown or HTML leaking into rendered descriptions is a cross-cutting failure: WCAG 2.2 SC 1.3.1 (Info and Relationships) requires that semantic structure conveyed through presentation be programmatically determinable, and an <img> tag or **bold** shown as literal characters is unreadable by screen readers. Beyond accessibility, unrendered markup is a OWASP A03 injection surface — if user-supplied HTML is echoed without sanitization, even a markdown renderer can be weaponized via unsanitized <script> tags or event-handler attributes. Directories that accept owner-submitted descriptions and pass them directly to innerHTML without sanitization are one malicious description away from stored XSS affecting all visitors to that listing page.
Severity rationale
Low for raw-markup display because the failure is a rendering bug, not an injection vulnerability — but severity escalates to high if the description is rendered via unsanitized `dangerouslySetInnerHTML`.
Remediation
Render markdown through a sanitizing parser. react-markdown is safe by default; if you need raw HTML support, pair rehype-raw with rehype-sanitize to strip script tags and event handlers.
// components/listing/description.tsx
import ReactMarkdown from 'react-markdown';
import rehypeSanitize from 'rehype-sanitize';
export function ListingDescription({ markdown }: { markdown: string }) {
return (
<ReactMarkdown rehypePlugins={[rehypeSanitize]}>
{markdown}
</ReactMarkdown>
);
}
Never pass raw description strings to dangerouslySetInnerHTML without sanitization. If your descriptions are plain-text only, set that as a schema constraint at the database layer and strip formatting characters on write.
Detection
-
ID:
description-rendering -
Severity:
low -
What to look for: Enumerate all listing descriptions in the UI. For each, if descriptions allow formatting (markdown, HTML), check a test listing with formatted text. Verify that formatted text is rendered correctly and not shown as raw markup.
-
Pass criteria: Formatted descriptions (markdown or HTML) are properly parsed and rendered. No raw markup is visible to users — 100% of descriptions must be sanitized against XSS while preserving basic formatting. Report: "X descriptions rendered, all Y properly sanitized and formatted."
-
Fail criteria: Formatted descriptions show raw
<b>,**, or markdown syntax in the rendered output. -
Skip (N/A) when: Descriptions are plain text only.
-
Detail on fail: Example:
"Description with markdown shows '**Featured Menu**' instead of bold" -
Remediation: Properly parse and render formatted descriptions:
import ReactMarkdown from 'react-markdown' <ReactMarkdown>{listing.description}</ReactMarkdown>
External references
- cwe · CWE-79 — Improper Neutralization of Input During Web Page Generation (XSS)
- owasp:2021 · A03 — Injection — unsanitized user-supplied markup rendered as HTML
- wcag:2.2 · 1.3.1 — Info and Relationships
Taxons
History
- 2026-04-18·v1.0.0·Initial import from directory-listing-schema·automated