Trusted Types
Problem
Developers accidentally introduce DOM-based XSS by passing unsanitized strings to dangerous APIs like innerHTML, eval, or document.write. These vulnerabilities are hard to spot in code reviews and can execute attacker-controlled code even when server-side protections are in place.
Solution
Require type wrappers for dangerous operations like setting innerHTML to prevent injection attacks. This makes XSS vulnerabilities harder to introduce accidentally.
Example
This demonstrates using browser Trusted Types API to enforce type checking on dangerous operations like innerHTML, preventing DOM-based XSS vulnerabilities by requiring explicit sanitization.
// Create trusted types policy with sanitization
const policy = trustedTypes.createPolicy('myPolicy', {
createHTML: (string) => DOMPurify.sanitize(string) // Sanitize before creating trusted type
});
// Use trusted type - browser requires this for innerHTML
element.innerHTML = policy.createHTML(userInput); // Safe - sanitized by policy
Benefits
- Eliminates DOM-based XSS by forcing sanitization at dangerous sinks.
- Provides browser-level enforcement that can’t be bypassed.
- Makes security violations obvious during development.
- Works alongside Content Security Policy for defense-in-depth.
Tradeoffs
- Requires browser support which is still limited.
- Needs refactoring existing code to use trusted type policies.
- Can break third-party libraries that use innerHTML or eval.
- Adds complexity with policy creation and management.