What Is the Trusted Types API and How Does It Prevent DOM XSS?
Learn how the Trusted Types API blocks raw strings from dangerous DOM sinks like innerHTML to prevent DOM-based XSS.
Expected Interview Answer
The Trusted Types API is a browser-enforced mechanism, activated via a CSP directive, that blocks a page’s dangerous DOM sinks — like innerHTML or eval — from accepting raw strings at all, forcing every value passed to those sinks to first go through an explicitly defined, auditable sanitizing policy that produces a typed, trusted object.
Most DOM-based XSS happens because a dangerous sink such as element.innerHTML, document.write, or eval() accepts a plain string, and somewhere in the app a raw, unsanitized value derived from user input or a URL parameter ends up passed directly into one of those sinks. With Trusted Types enforced via require-trusted-types-for 'script' in the CSP header, browsers that support it change the type signature of those sinks: they throw a TypeError if a plain string is assigned instead of a TrustedHTML, TrustedScript, or TrustedScriptURL object. Developers must create one or more named policies via trustedTypes.createPolicy(), each with explicit createHTML/createScript/createScriptURL functions that perform the actual sanitization or escaping logic, and only objects produced by an approved policy are accepted by the sinks. This converts DOM XSS from a runtime risk that depends on catching every unsafe call during code review into a build-time and runtime enforced contract: any code path that tries to assign an unsanitized string to innerHTML simply throws, and violations can also be reported via CSP reporting endpoints before enforcement, making it possible to audit an entire codebase’s risky sink usage before turning on hard enforcement.
- Makes it impossible to assign raw strings to dangerous DOM sinks like innerHTML
- Forces all sink-bound values through explicit, auditable sanitizing policies
- Converts a class of runtime XSS risk into a browser-enforced type contract
- Supports a report-only mode to audit unsafe sink usage before hard enforcement
AI Mentor Explanation
Trusted Types is like a stadium redesigning its turnstiles so they physically cannot accept a hand-written paper ticket anymore — only a laminated, officially stamped pass produced by the box office counts. Anyone trying to shove in a plain slip of paper gets rejected at the gate, no matter how convincing it looks. The box office is the only place authorized to produce the laminated passes, and it checks each request before stamping one. That structural change — refusing raw input entirely and requiring a vetted, typed pass — is exactly what Trusted Types does to dangerous DOM sinks like innerHTML.
Step-by-Step Explanation
Step 1
Enforce via CSP
The server sends Content-Security-Policy: require-trusted-types-for 'script', switching supporting browsers into enforcement mode.
Step 2
Define named policies
The app calls trustedTypes.createPolicy(name, { createHTML, createScript, createScriptURL }) with explicit sanitization logic for each rule.
Step 3
Sinks require typed objects
Dangerous sinks like innerHTML now only accept TrustedHTML/TrustedScript/TrustedScriptURL objects produced by an approved policy.
Step 4
Raw string assignment throws
Any code path still assigning a plain string to a guarded sink throws a TypeError at runtime, surfacing the unsafe call immediately.
What Interviewer Expects
- Explaining that Trusted Types changes dangerous sinks’ accepted type, not just adds a linter warning
- Understanding the role of createPolicy and its create* functions
- Awareness of report-only mode for auditing before hard enforcement
- Distinguishing Trusted Types from general CSP script-src restrictions
Common Mistakes
- Assuming Trusted Types automatically sanitizes content without an explicit policy being written
- Confusing Trusted Types with a CSP nonce or hash mechanism
- Not accounting for third-party libraries that assign raw strings to innerHTML directly
- Rolling out hard enforcement without first running in report-only mode to find violations
Best Answer (HR Friendly)
“Trusted Types is a browser feature that makes it technically impossible for risky code — like setting innerHTML — to accept plain, unchecked text. Every piece of content has to pass through an approved, reviewed function first, so even if a bug tries to inject unsafe content into the page, the browser itself blocks it.”
Code Example
// CSP header sent by the server:
// Content-Security-Policy: require-trusted-types-for 'script'; trusted-types app-policy
if (window.trustedTypes && trustedTypes.createPolicy) {
const appPolicy = trustedTypes.createPolicy('app-policy', {
createHTML: (input) => sanitizeHtml(input), // your escaping/sanitizing function
createScriptURL: (input) => {
const allowed = ['https://cdn.trusted.example.com/']
if (!allowed.some((prefix) => input.startsWith(prefix))) {
throw new Error('Untrusted script URL blocked')
}
return input
},
})
const el = document.getElementById('output')
el.innerHTML = appPolicy.createHTML(userSuppliedContent) // required, plain string now throws
}Follow-up Questions
- What happens if you assign a raw string to innerHTML after Trusted Types enforcement is on?
- How would you roll out Trusted Types incrementally on a large existing codebase?
- How does Trusted Types relate to the trusted-types CSP directive that lists allowed policy names?
- Which browsers currently support Trusted Types, and what is the fallback strategy for others?
MCQ Practice
1. What does the Trusted Types API primarily prevent?
Trusted Types blocks dangerous DOM sinks from accepting untyped, unsanitized strings, directly targeting DOM XSS.
2. What happens when a plain string is assigned to innerHTML with Trusted Types enforced?
Enforcement changes the sink to require a TrustedHTML object; a plain string assignment throws an error instead of executing.
3. What must a developer define to legally produce a value accepted by a guarded sink?
Only objects produced by an approved createPolicy() policy, with its own sanitization logic, are accepted by guarded sinks.
Flash Cards
What is the Trusted Types API? — A browser mechanism that blocks dangerous DOM sinks from accepting raw strings, requiring typed objects from an approved policy.
How is it enforced? — Via the CSP directive require-trusted-types-for 'script'.
What throws if bypassed? — Assigning a raw string to a guarded sink like innerHTML throws a TypeError under enforcement.
How to audit before enforcing? — Use CSP report-only mode to log violations without blocking, before switching to hard enforcement.