Sanitization and XSS Defence

When users supply markup (comments, rich-text editors), textContent is too strict and innerHTML is an XSS hole (Parsing HTML Strings). A sanitizer parses the markup with the browser's own parser and keeps only allowed elements, attributes and URL schemes. DOMPurify 17,413 (https://github.com/cure53/DOMPurify 17,413 ) 3.4.15 (September 2026, MPL-2.0 or Apache-2.0, npm 2,036 install dompurify) runs in all modern browsers and is tuned with ALLOWED_TAGS, FORBID_ATTR or addHook(); servers need a DOM such as jsdom 21,691 . The built-in setHTML() can never keep scripts or handlers, but Safari 10 lacks it. Trusted Types (Sandboxing and Trusted Types) make sinks accept only policy output.

A default Trusted Types policy backed by DOMPurify, beside setHTML()HTMLLive
<!doctype html>
<meta http-equiv="Content-Security-Policy"
  content="require-trusted-types-for 'script'; trusted-types default dompurify">
<script src="https://cdn.jsdelivr.net/npm/dompurify@3.4.15/dist/purify.min.js"></script>
<pre id="out" style="font: 13px/1.5 monospace; margin: 0"></pre>
<script>
  const dirty = '<p onclick="steal()">Hi <img src=x onerror="steal()"><b>bold</b> '
    + '<a href="javascript:steal()">link</a><script>steal()<\/script></p>';
  trustedTypes.createPolicy('default', {  // runs whenever a plain string reaches a sink
    createHTML: (html) => DOMPurify.sanitize(html),
  });
  const box = document.createElement('div');
  box.innerHTML = dirty;  // allowed, but sanitized by the default policy first
  const lines = [`DOMPurify ${DOMPurify.version}: ${box.innerHTML}`];
  if ('setHTML' in box) lines.push(`setHTML(): ${(box.setHTML(dirty), box.innerHTML)}`);
  document.querySelector('#out').textContent = lines.join('\n');
</script>
Browser output of Listing 8.59
Browser output of 59

Both removed the handlers, the javascript: URL and the script; setHTML() also dropped the image. List dompurify in trusted-types: it is the policy DOMPurify uses for its own parsing, and with TRUSTED_TYPES_POLICY: null under enforcement Chrome 152 1 returned an empty string. Sanitize at insertion time, not when saving. Pin and update the library: DOMPurify published ten security advisories between May and August 2026.