Safety
Trusted Types vs CSP for DOM XSS Defense
March 30, 2026
Trusted Types vs CSP for DOM XSS is two layers, not a replacement. Content-Security-Policy script-src (nonces, hashes, no unsafe-inline) limits which scripts load. Trusted Types (CSP trusted-types and require-trusted-types-for 'script') limits assigning untrusted strings into sinks like innerHTML in supporting browsers. A brochure site with three first-party files should enforce CSP before considering Trusted Types. A SPA that still concatenates HTML in the client is the audience for Trusted Types — after the policy is real, not Report-Only cosplay. RoastMyOpsec reads CSP quality signals on the primary HTML response. It does not inject DOM XSS and it does not grade a full Trusted Types policy as a pass/fail today.
The practical difference
CSP is mostly about what may execute as a script or load as a frame. Trusted Types is about how JavaScript is allowed to write into the document. You can have a tight script-src and still innerHTML a reflected string. You can have Trusted Types and still load a hostile script if CSP is wide open.
Browser support is uneven. Treat Trusted Types as progressive hardening, not a checkbox for every marketing CMS.
How to choose based on the stack
WordPress brochure: enforce CSP (including frame-ancestors), skip Trusted Types until a custom theme is actually doing DOM writes. React/Vue with a compiler that avoids innerHTML: CSP first; Trusted Types if you have remaining sinks. Legacy jQuery HTML strings: plan Trusted Types in the app, not as a CDN header copied from a lab.
| Control | Stops | Does not stop | Takeaway |
|---|---|---|---|
| Enforcing CSP script-src | Unexpected script URLs / inline without nonce | DOM writes by an allowed script | Do this first |
| Trusted Types | Raw strings into supported sinks | Logic bugs; unsupported browsers | App hardening after CSP |
| Report-Only CSP | Nothing | Everything | See report-only vs enforcing |
| HttpOnly cookies | JS reading the session cookie | DOM XSS acting as the user | Still required |
What the roast can see
CSP header presence and looseness (unsafe-inline, wild hosts). A trusted-types directive in CSP may show up as a quality signal later; do not wait for the scanner to invent a Trusted Types program. Pair with nonces vs hashes.
Common mistakes
The first mistake is Trusted Types with default-src * and unsafe-inline.
The second mistake is a policy that allows a duplicate 'default' policy that accepts every string.
The third mistake is enabling require-trusted-types-for on a CMS you do not compile.
Free audit the URL you own
RoastMyOpsec is a defensive public-surface roast: headers, cookies, sensitive paths, and more — no exploit payloads. Start with the free audit, then open the vault if the blurred findings look expensive.
Free audit nowFAQ
- Does Trusted Types replace CSP?
- No. Enforce CSP first. Add Trusted Types when your JavaScript still writes HTML strings into the DOM.
- Should every marketing site ship Trusted Types?
- Usually no. Finish framing, HSTS, and a real script-src. Trusted Types is for apps with DOM sinks, not for a static brochure.
- Does RoastMyOpsec test DOM XSS?
- No. Header read only. No payloads, no sink fuzzing.