The Google Chrome team announces an experimental Trusted Types API to help combat DOM Cross-Site Scripting (XSS) security vulnerabilities. Google's Vulnerability Reward Program reports that DOM XSS is the most common XSS security variant.
Krzysztof Kotowicz, a software engineer focused on security at Google, explains the challenges developers face with XSS:
Practice shows that maintaining an XSS-free application is still a difficult challenge, especially if the application is complex. While solutions for preventing server-side XSS are well known, DOM-based Cross-Site Scripting (DOM XSS) is a growing problem.
The challenge is that XSS is easy to introduce, but challenging to detect.
Trusted Types could address these XSS problems at their root cause, helping eliminate DOM XSS vulnerabilities.
Trusted Types allow developers to lock down dangerous injection sinks so they become secure by default and cannot get called with strings. The Content Security Policy (CSP) HTTP response header sets Content-Security-Policy: trusted-types *
to leverage trusted types.
This prevents common sources of XSS, such as this example provided from the Google example:
const templateId = location.hash.match(/tplid=([^;&]*)/)[1];
// typeof templateId == "string"
document.head.innerHTML += templateId // Throws a TypeError.
Trusted Types introduces a new global which gets used instead through the setting of a policy:
const templatePolicy = TrustedTypes.createPolicy('template', {
createHTML: (templateId) => {
const tpl = templateId;
if (/^[0-9a-z-]$/.test(tpl)) {
return `<link rel="stylesheet" href="./templates/${tpl}/style.css">`;
}
throw new TypeError();
}
});
const html = templatePolicy.createHTML(location.hash.match(/tplid=([^;&]*)/)[1]);
// html instanceof TrustedHTML
document.head.innerHTML += html;
The template policy verifies the passed template ID parameter before creating the resulting HTML. The policy object wraps the user-defined createHTML
function in a Trusted Type object. Beyond verifying that the templateId
is valid to fix XSS, the only code that could introduce DOM XSS vulnerabilities is now the code of the policies, reducing the areas of a code base to review for DOM XSS security issues.
Current Trusted Types include HTML, URL, ScriptURL, and Script. The CSP for trusted types may be limited to one or all Trusted Types policies.
Developers can try trusted types on live websites or web apps with Chrome by registering for the Trusted Types Origin Trial, or may enable this feature on local installations of Chrome via the command-line, chrome --enable-blink-features=TrustedDOMTypes
, or within Chrome by opening chrome://flags/#enable-experimental-web-platform-features
.
A Trusted Types polyfill also exists to try this feature within other browsers. Two variants of the browser polyfill exist, one that only supports the API so that codebases with trusted types still work in older browsers, and a full option that also enables type enforcement in the DOM based on the CSP policy from the document. A demo with the Trusted Types polyfill is available.
Issues and feedback may get reported to the WICG Trusted Types GitHub project, or discussed on the trusted-types Google Group. Contributions to the trusted types specification are welcome via the WICG contribution guidelines.