Trusted Types are an emerging DOM API specification that attempt to prevent a whole range of attacks resulting from web browsers being tricked into execution of untrusted content, for example XSS.

As of April 2020 Trusted Types are in draft state but are implemented in Google Chrome as an "experimental" option, which did not prevent us from implementing it for the whole WebCookies.org. This was facilitated by the fact that the website is mostly static and JavaScript is primarily used for some trivial user interaction (menus) and API calls for scan updates etc.

TT happens fully on the browser side and doesn't have any server-side components and its whole purpose of TT is to create a centrally managed flow for all possibly untrusted data inside browser's DOM which will ensure untrusted data is made safe by either validation or sanitization. The following code should be part of your website's main JavaScript library.

First goes a no-op shim for browsers that do not support TT:

if (typeof TrustedTypes === 'undefined') TrustedTypes = {createPolicy: (name, rules) => rules};

Next we declare our primary TT policy called base:

const ttp = TrustedTypes.createPolicy('base', {

    createHTML: (input) => input,

    createScriptURL: (input) => {
        const url = new URL(input, document.baseURI);
        if (url.origin === window.location.origin || url.origin === "s.osano.com") return url.href;
        throw new TypeError('createScriptURL: invalid URL');
    }
});

This piece of code is generally all that TT does: validate and/or sanitize potentially untrusted data of standardized types. Here we handle only "trusted HTML" type created by createHTML method and "trusted URL" created by createScriptURL. Only these methods in a TT-enabled browser are entitled to create these trusted objects, and in due course any risky destinations ("sinks") will only accept these trusted objects.This is a concept well-known from other secure coding frameworks, such as safestring in Django. The idea is simple: any data that has passed through these two methods is marked as secure, and any data that hasn't will be rejected.

Now, you might be puzzled by the fact that the createHTML method doesn't really do any validation here: this is because our website does not inject any untrusted content within DOM. Our threat model assumes that all calls to this method will originate internally, from static HTML created by the server or from our own API. If your service is processing any user-generated or external data, you want to plug in something like DOMPurify here — a secure, validating HTML parser that will only accept whitelisted HTML elements.

The createScriptURL is simple: it only allows relative URLs (within the same origin) or URLs from trusted, whitelisted origins.

These two methods basically define what we consider as "trusted" content within the DOM on our website.

Now, about the actual usage — whenever you actually send potentially untrusted data to a potentially risky destination such as eval() or .innerHTML or XMLHttpRequest, you always wrap it in the TT policy method:

let r = new XMLHttpRequest();
r.open("GET", ttp.createScriptURL(progress_url), true);
Fully automated RESTful API is now available. Subscribe for your free trial today!