HTML Sanitization
HTML sanitization strips executable content from untrusted markup via an allowlist parse — safe tags and attributes only — because blocklist string filtering of HTML is a losing game.
Definition
HTML sanitization parses untrusted markup and re-serializes only allowlisted elements, attributes, and URL schemes, dropping event handlers, javascript URLs, and dangerous elements like script and iframe. Allowlist parsing works because the parser, not regex filtering, decides what the browser will see. It is required whenever rich HTML input must render as HTML.
Context and scope
Used for rich-text editors, comment systems, email rendering, markdown renderers with raw HTML enabled, and CMS imports.
Common misconceptions
- Escaping the input is equivalent — encoding renders data as text; sanitization lets safe markup render as markup; pick per requirement
- Sanitize on render rather than ingest — sanitize once at ingest into canonical safe HTML, and store the sanitized result
- The sanitizer config is set and forget — browser parse quirks evolve; unmaintained sanitizers accumulate bypasses
Anti-patterns
- Filtering dangerous tags by string replacement and losing to nested and malformed markup
- Allowing style attributes and href without scheme validation, opening expression and javascript URLs
- Running sanitization client-side only and persisting raw HTML to the database
Related concepts
Related examples
Authoritative source
What it is
Rich input contains markup the author intends plus markup the attacker injects. A sanitizer separates them by parsing into a DOM, walking it, and keeping only known-safe constructs. The output is HTML that still renders formatting while every executable path — script, handler, dangerous URL — has been structurally removed.
How it works
The pipeline: parse with the same engine class that will render, allowlist elements and attributes, validate URL schemes and safe values, drop or neutralize the rest, then serialize. DOMPurify is the maintained reference; server-side equivalents exist per language. Configuration decides the security envelope: every added tag or attribute is a reviewed decision.
When to use it
Anywhere user markup must render as HTML: comments, bios, email bodies, imported CMS content. Where full fidelity is not required, markdown without raw HTML or plain text with escaping is simpler and safer.
Pitfalls
Sanitize where you trust boundary definition — client-side sanitization can be bypassed by direct API calls. Storage and rendering must agree: store sanitized canonical HTML, render it without re-processing. mXSS attacks target the round-trip between parser and serializer — keep sanitizers current and test with mutation corpora.