Content Security Policy (CSP)
Quick Reference Guide


The CSP trusted-types Directive

The trusted-types Content Security Policy (CSP) directive is typically used in conjunction with the require-trusted-types-for CSP directive to instructs the browser to require the use of trustedTypes when passing a string to an unsafe DOM sink (such as innerHTML).

The trustedTypes JavaScript api was implemented in Chrome & Edge in 2020 which lets developers mark HTML as trusted before passing it to a dangerous sink within the DOM api, such as innerHTML or document.write. The require-trusted-types-for CSP directive requires that the trustedTypes API is used, while the trusted-types directive limits the names of the policies in use. HTML is marked as TrustedHTML via the createHTML function of the policy. You can also use createScriptURL() to create a TrustedScriptURL object, or createScript() to create a TrustedScript object.

Example of Trusted Types

Here's our old unsafe code:

untrusted_data = "123";
unsafe_html = '<div class="wrapper">' + untrusted_data + '</div>';
element = document.getElementById('content');
element.innerHTML = untrusted_data;

Now here's how we might rewrite this in a way that is safe (by using innerText), and also marking it as TrustedHTML:

untrusted_data = "123";
myPolicy = trustedTypes.createPolicy("myPolicy", {
    createHTML: function(input) {
        var div = document.createElement("div");
        div.classList.add('wrapper');
        if (input.match(/^[0-9]+$/)) {
            div.innerText = input;
        } else {
            div.innerText = "0";
        }
        return div.outerHTML;
    }
});
element = document.getElementById('content');
element.innerHTML = myPolicy.createHTML(untrusted_data);

In this example the call to myPolicy.createHTML(untrusted_data) returns a TrustedHTML object.

Example of an Unsafe Policy

It is certainly possible to create policies that are not actually safe, here we can take our old code and create an unsafe policy. We didn't improve security in this example, we are only bypassing the CSP restriction.

untrusted_data = "123";
myUnsafePolicy = trustedTypes.createPolicy("myUnsafePolicy", {
    createHTML: function(input) {
        return '<div class="wrapper">' + input + '</div>';
    }
});
element = document.getElementById('content');
element.innerHTML = mySanitizerPolicy.createHTML(untrusted_data);

Example trusted-types CSP Directive

The trusted-types directive is used along with the require-trusted-types-for directive.

Content-Security-Policy: require-trusted-types-for 'script';trusted-types myPolicy

In this example we are requiring the use of trusted types via the require-trusted-types-for directive, and then limiting the list of allowed trusted type policies with the trusted-types directive.

In this example only myPolicy may be used, even if we attempt to define myUnsafePolicy it will not be allowed.

In fact, we will actually get two errors now:

Refused to create a TrustedTypePolicy named 'myUnsafePolicy' because it violates the following Content Security Policy directive: "trusted-types myPolicy"

And we will get this error caused by the trustedTypes.createPolicy("myUnsafePolicy", ...) line.

Uncaught TypeError: Failed to execute 'createPolicy' on 'TrustedTypePolicyFactory': Policy "myUnsafePolicy" disallowed

Why limit trusted type policies by name?

It is possible that a malicious script could create its own unsafe policies, so by listing the policies you are denoting these policies as safe and trusted within your application to sanitize HTML, create scripts or create script urls.

JavaScript Framework Support for Trusted Types

Some JavaScript Frameworks provide built-in support for Trusted Types.

Angular trusted-types

Angular has had built-in support for Trusted Types since Angular 11. If you use Angular or you'll need to add the trusted type named angular to your CSP trusted-types directive when using the require-trusted-types-for 'script' directive.

In addition to the angular type there are a few other built-in trusted type policies. If your Angular Application uses any of the bypassSecurity functions such as bypassSecurityTrustHtml then you'll need to add angular#unsafe-bypass to your trusted-types list. Additionally angular may define the policies: angular#bundler, angular#unsafe-jit and angular#unsafe-upgrade depending on features used.

DOMPurify Trusted Types Support

The DOMPurify HTML sanitizer library can return TrustedHTML objects by passing RETURN_TRUSTED_TYPE: true into the sanitize function. For example:

DOMPurify.sanitize(input, {RETURN_TRUSTED_TYPE: true})

DOMPurify will create a policy named dompurify by default. You can customize this policy name by adding the attribute data-tt-policy-suffix to the Script element used to load DOMPurify. If you had data-tt-policy-suffix="mysuffix" then the policy would be named dompurify#mysuffix

You could also create your own trusted types policy that uses DOMPurify like this:

if (window.trustedTypes && trustedTypes.createPolicy && DOMPurify) {
    trustedTypes.createPolicy("default", {
        createHTML: (input) => DOMPurify.sanitize(input, {RETURN_TRUSTED_TYPE: false})
    });
}

In the above example the name of the trusted types policy created is called default.


Browser Support for trusted-types

W3C Working Draft


Supported On:


Chrome 83+ (2020)
Edge 83+ (2020)


Not Supported On:


Firefox Not Yet Supported
Safari Not Yet Supported
Internet Explorer

Note, a trustedTypes polyfill is available from the w3c, but the require-trusted-types-for directive and the trusted-types directive will still be ignored.

CSP Developer Field Guide

CSP Developer Field Guide

Want to learn the ins and outs CSP? Grab a copy of the CSP Developer Field Guide. It's a short and sweet guide to help developers get up to speed quickly.

Grab a Copy

Struggling to stay on top of security advisories?

Advisory Week is a weekly roundup of all the security advisories published by the major software vendors.