CodePark/ questions / XSS: sources, sinks & sanitizing
START PRACTICINGPRACTICE
Frontend question · Frontend security › XSS: sources, sinks & sanitizing

What are Trusted Types, and how do they help stop DOM-based XSS?

// Header: Content-Security-Policy: require-trusted-types-for 'script'; trusted-types sanitize
const policy = trustedTypes.createPolicy("sanitize", {
  createHTML: (input) => DOMPurify.sanitize(input),
});

el.innerHTML = userHtml;                     // throws: a plain string is rejected
el.innerHTML = policy.createHTML(userHtml);  // allowed: a TrustedHTML object

Trusted Types is a browser feature that makes the dangerous DOM sinks reject plain strings. You turn it on with the CSP directive require-trusted-types-for 'script'.

Once it is on, sinks like innerHTML, eval and a script element's src only accept special objects:

  • TrustedHTML for HTML sinks
  • TrustedScript for code sinks
  • TrustedScriptURL for script URLs

Only a policy can create these objects. You create a policy with trustedTypes.createPolicy(name, rules). The trusted-types directive lists which policy names may exist.

Why this helps: without Trusted Types, any line in your app or its libraries could pass user data to innerHTML. With them, every dangerous write must go through a few small policies. Those are easy to review, and one of them can call DOMPurify. A forgotten innerHTML now throws an error instead of becoming a security bug.

To adopt it:

  • Start with Content-Security-Policy-Report-Only to find every place that breaks.
  • A policy named default catches old code that still assigns strings.

Support started in Chromium-based browsers. Check MDN for current support in other browsers. Browsers without support ignore the directive, so keep your other XSS defences too.

  • Trusted Types make sinks like innerHTML reject plain strings.
  • You turn them on with the CSP directive require-trusted-types-for 'script'.
  • Only policies made with trustedTypes.createPolicy can create trusted values.
  • All dangerous writes then go through a few policies that are easy to review.
  • Roll it out in report-only mode first, and keep other defences for browsers without support.