← Concepts

阅读中文版本

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.

security

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

https://github.com/cure53/DOMPurify

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.