Trusted Types Policy Builder
Build a Trusted Types policy skeleton and the CSP directives that enforce it, with a report-only rollout plan and framework-specific notes.
Runs locallyEverything happens in your browser. What you paste or drop here is never uploaded, logged or stored.
Use the tool
- # = _ / @ . % only.
What a Trusted Types policy is
When Trusted Types is enforced, the browser stops accepting plain strings at the DOM functions that
can introduce code. Assigning a string to innerHTML throws. The only values those
functions will accept are TrustedHTML, TrustedScript and
TrustedScriptURL objects, and the only way to obtain one is to pass a string through a
policy you created and named.
That policy is a small object with up to three functions. This tool writes it, along with the CSP directives that turn enforcement on and the server configuration to deliver them - in the order they should actually be deployed.
Why this tool will not generate a pass-through policy
The shortest policy that makes the errors go away is this one:
createHTML: (input) => input
It compiles. The browser accepts it. Every TypeError disappears and the migration
looks finished. It also provides no protection whatsoever - every string that
reached innerHTML before still reaches it, now wearing a wrapper that declares it
trusted.
This is worse than not adopting Trusted Types at all, because the codebase now looks as though it has been reviewed. So this tool does not emit that policy. Choose a sanitiser and you get one; choose None and you get a policy that HTML-escapes its input, which is safe and visibly restrictive rather than safe-looking and permissive.
On the createScript function
If you enable TrustedScript, the generated function throws. That is intentional.
Compiling a string into executable code is precisely the thing Trusted Types exists to prevent, and
there is no safe general implementation to offer. If your application genuinely needs one, it
should be written deliberately and reviewed - not produced by a form.
On the createScriptURL function
The generated version compares url.origin against an explicit allow-list. It does not
use a regular expression or a substring test, and that distinction is the whole point:
cdn.example.com appears inside cdn.example.com.attacker.test, so any
check weaker than an origin comparison can be walked straight past. Parsing with URL
and comparing the resulting origin is the only reliable form.
Restricting which policies can exist
Creating a policy is itself a privileged act. Without a restriction, injected script can call
trustedTypes.createPolicy and mint its own trusted values, which defeats the entire
mechanism. The trusted-types directive names the policies that may be created and
blocks the rest.
The default policy is a special case worth understanding. If it exists, the browser
applies it automatically wherever a plain string is passed to a sink, which makes migration far
easier because unconverted code keeps working. It is also a single function that every unconverted
sink now flows through, so it must sanitise properly - and it should be a migration step rather
than a destination.
Deploy in this order
- Ship the policy creation code on its own. It does nothing until enforcement is on, so this is a safe, boring deploy.
- Convert call sites, starting with the ones that only need
textContent. - Turn on
Content-Security-Policy-Report-Only: require-trusted-types-for 'script'. Nothing breaks; violations are reported. - Read the reports with CSP Report Analyzer and convert what they find.
- Move to the enforcing header once the reports are clean.
Going straight to enforcement turns every unconverted sink into a thrown error, which for most applications means a blank page for whichever visitors reach that code path first. Use Trusted Types Readiness Checker to size the work before you start, and CSP Generator to fold these directives into your wider policy.
Everything here is generated in your browser
The policy name, your sanitiser choice and the generated code never leave the page. There is nothing to upload - the output is text assembled locally from the options you selected.
Frequently asked questions
Will this break browsers that do not support Trusted Types?
No. The generated code is guarded with if (window.trustedTypes), and browsers
without support ignore the CSP directives entirely and behave exactly as before. It is a
defence-in-depth measure, so partial support reduces its reach without creating a problem.
Do I need the default policy?
Only as a migration aid. It makes unconverted code keep working by routing every plain string through one function, which is useful while you convert call sites and dangerous to leave forever - it becomes a single point that everything trusts. Convert the call sites and remove it.
Is DOMPurify necessary, or can I write my own sanitiser?
Use DOMPurify or another vetted library. HTML sanitisation is genuinely difficult - mutation XSS, namespace confusion and parser differences between browsers have all defeated hand-written sanitisers repeatedly. A regular expression over markup is not a sanitiser.
Can I have more than one policy?
Yes, and it is often a good idea - a narrow policy per subsystem is easier to review than
one permissive policy everything shares. List each name in the trusted-types
directive.
References
Related tools
Other Tools
Popular tools from across A2Z
Rate this tool
Was this tool useful? Your feedback helps us improve it.