RoastMyOpsec

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.

ControlStopsDoes not stopTakeaway
Enforcing CSP script-srcUnexpected script URLs / inline without nonceDOM writes by an allowed scriptDo this first
Trusted TypesRaw strings into supported sinksLogic bugs; unsupported browsersApp hardening after CSP
Report-Only CSPNothingEverythingSee report-only vs enforcing
HttpOnly cookiesJS reading the session cookieDOM XSS acting as the userStill 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 now

FAQ

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.

Sources

Related guides