Trusted Types and CSP: reducing DOM XSS risk
Learn how Trusted Types restrict dangerous browser injection sinks, how CSP enforcement works and how to migrate an existing web application safely.
Why Trusted Types matters in 2026
The W3C published a new Trusted Types Working Draft on 7 October 2026. Trusted Types addresses a recurring source of client-side cross-site scripting: application code sends an attacker-controlled string to a browser API that interprets it as HTML, script or a script URL. Common injection sinks include innerHTML, document.write, DOMParser operations, script text or source setters and direct code evaluation.
The API lets an application require special browser-created objects such as TrustedHTML instead of ordinary strings at protected sinks. Those objects can be produced only through named policies created by the application. This changes a scattered review problem into a smaller one: security reviewers can focus on the policies and the few approved abstractions that create trusted values. The specification remains a Working Draft, so teams must follow current browser support and changes.
Understand what the type proves
A Trusted Type records that a value passed through an application-defined policy. It does not automatically mean the value is safe. A policy that returns its input unchanged merely gives dangerous data a trusted wrapper. Policies should use a well-reviewed sanitizer or strict construction logic appropriate to the destination, reject unexpected input and remain independent of mutable global state that could alter their decision.
Prefer APIs that do not parse markup. Use textContent for plain text, DOM methods for known elements and attributes, and framework escaping for ordinary templates. Trusted Types is most valuable when an application cannot immediately remove every string-based sink. It acts as an enforcement boundary during migration and helps prevent future code or dependencies from silently reintroducing an unreviewed sink.
Connect enforcement to Content Security Policy
Trusted Types enforcement is enabled through Content Security Policy. The require-trusted-types-for 'script' directive tells a supporting browser to reject ordinary strings at covered DOM XSS sinks. The trusted-types directive can limit which policy names code may create. Keep policy names few, descriptive and owned by reviewed modules rather than allowing every feature or dependency to invent its own bypass.
Start with Content-Security-Policy-Report-Only so violations are reported without breaking users. Exercise every major route, editor, analytics integration and error state, then group violations by sink and call path. Reporting is evidence for migration, not proof of safety: unsupported browsers do not enforce it, test coverage can miss rare paths and reports may contain a short sample of the rejected value that deserves privacy review.
Migrate without creating one universal bypass
Inventory innerHTML, outerHTML, insertAdjacentHTML, document.write, eval-like behavior, script URL creation and third-party packages that reach them. Replace simple uses with safe DOM APIs. For markup that must remain dynamic, define the allowed elements, attributes, URL schemes and sanitizer behavior. Add tests with malicious strings, nested markup, event handlers, SVG and encoded URLs rather than testing only normal content.
A temporary default policy can reveal or adapt legacy calls, but it can also conceal how much unsafe behavior remains. Give it a removal plan and collect the call site for each invocation. Move approved creation into small modules, restrict allowed policy names in CSP and require security review for changes to those modules. Enforce on a staged audience only after report-only data is quiet and important workflows have been tested.
Combine Trusted Types with other defenses
Trusted Types does not prevent server-rendered XSS, malicious application code, unsafe data URLs, unprotected resource loading or every possible DOM construction pattern. Continue output encoding on the server, validate URLs, keep dependencies current and use a restrictive script-src policy with nonces or hashes where appropriate. Avoid unsafe-inline and unsafe-eval unless a documented legacy constraint makes a temporary exception unavoidable.
Test unsupported browsers because the application still needs safe coding patterns when enforcement is absent. Monitor CSP reports for new violations after releases, but rate-limit and protect the reporting endpoint. Treat a violation as a defect to investigate, not a value to whitelist automatically. The goal is to remove risky string-to-code paths and keep the remaining trusted-value creation narrow and explainable.
Worked example: migrate an HTML preview
Imagine an administration page that previews formatted announcements by assigning editor output to innerHTML. First determine whether formatting is required; if not, replace it with textContent. If a controlled subset of HTML is necessary, sanitize against an explicit allow-list in one reviewed policy and remove scripts, event attributes, dangerous URLs and unsupported elements. Test pasted content and hostile payloads as well as normal headings and links.
Enable report-only enforcement in staging and production, confirm all preview and error paths, then add the enforcing header with only the approved policy name. Keep server-side sanitization if announcements are stored or rendered elsewhere. The browser policy protects this sink in supporting clients; it does not make stored untrusted markup safe for email, mobile applications or another website with different controls.
Quick checklist
- Inventory DOM injection sinks and their callers.
- Replace markup parsing with safe DOM APIs where possible.
- Keep policies few, strict and independently reviewed.
- Begin with CSP report-only deployment.
- Test malicious HTML, SVG, URLs and rare application paths.
- Retain server encoding, dependency updates and restrictive script policy.
Primary references
Standards and platform support change. Use these authoritative sources to check the current specification and migration guidance.
