Content Security Policy is the most widely recommended defense against cross-site scripting. And for server-reflected XSS, it works well. A strict CSP with nonce-based script allowlisting prevents the browser from executing injected script tags. But there is an entire class of XSS that CSP does not touch: DOM-based XSS.
DOM XSS happens when client-side JavaScript takes untrusted input and passes it to a dangerous API like innerHTML, document.write, or eval. The attack never involves a script tag. The malicious code flows through legitimate JavaScript functions into DOM sinks that interpret strings as HTML or code. CSP sees nothing wrong because no policy violation occurred.
The sink problem
The DOM has about 60 APIs that accept strings and interpret them as HTML, JavaScript, or URLs. These are called injection sinks. The most common are innerHTML, outerHTML, document.write, eval, setTimeout with string arguments, and location.href assignments.
When any of these sinks receives attacker-controlled input, the browser executes whatever code is embedded in that input. A user-supplied search query that gets inserted via innerHTML without sanitization is all it takes.
Traditional defenses rely on developer discipline: sanitize every input, escape every output, review every code path. This works in theory. In practice, one missed sink in a codebase of thousands of JavaScript files is enough.
How Trusted Types work
Trusted Types is a browser API that changes the rules. Instead of trusting developers to sanitize correctly every time, it makes the browser enforce the rule: dangerous sinks only accept Trusted Type objects, not raw strings.
You enable it via CSP:
Content-Security-Policy: require-trusted-types-for 'script'
With this header, any attempt to assign a raw string to innerHTML or pass a string to eval throws a TypeError. The code must create a TrustedHTML, TrustedScript, or TrustedScriptURL object through a policy function that performs sanitization. No policy, no execution.
This flips the security model. Instead of hoping every developer remembers to sanitize, the browser blocks execution unless sanitization provably happened. The attack surface shrinks from "every sink in the codebase" to "the policy functions."
What the audit checks
The Trusted Types Audit checks two things. First, whether your CSP includes require-trusted-types-for 'script' to enable enforcement. Second, it scans your page's JavaScript for raw DOM sink usage that would violate a Trusted Types policy.
It identifies every innerHTML assignment, every document.write call, every eval invocation, and every other sink in your client-side code. These are the locations that would break under Trusted Types enforcement and that need to be wrapped in policy functions.
This gives you a migration path. You see exactly how many sinks exist, where they are, and what needs to change before you can flip the switch to enforcement.
Why adoption matters now
Google has been pushing Trusted Types since 2019 and uses them internally on many of its own properties. Chrome ships full support. The specification is at the W3C candidate recommendation stage. As AI-generated code becomes more common on the web, the risk of unsanitized DOM sinks increases because AI code generators frequently use innerHTML for convenience.
If you are building web applications that handle user input, which is almost every web application, Trusted Types is the strongest available defense against DOM XSS. It is not a replacement for CSP. It is the complement that closes the gap CSP leaves open.
For anyone building client-facing tools and sites on lean budgets, as I cover in The $97 Launch, Trusted Types cost nothing to implement on a new project. Adding them to an existing codebase takes more work, which is exactly why the audit tool exists: to show you the scope before you commit.
Fact-check notes and sources
- Trusted Types specification: W3C Candidate Recommendation. Source: w3.org/TR/trusted-types/.
- Chrome shipped Trusted Types enforcement in Chrome 83 (May 2020). Source: Chrome Platform Status.
- DOM XSS represents a significant portion of XSS vulnerabilities. Source: OWASP, "DOM Based XSS" documentation.
- Google uses Trusted Types internally on properties including Gmail. Source: Google Security Blog, "Trusted Types help prevent Cross-Site Scripting" (2020).
Related reading
- CSP strictness audit — the server-side half of script execution control
- Inline event handler audit — another CSP-hostile pattern
- SRI for CDN script integrity — protecting the scripts themselves
- API secret leakage — another class of client-side exposure
This post is informational, not security consulting advice. Mentions of Google and Chrome are nominative fair use. No affiliation is implied.