diff --git a/dist/spec/index.html b/dist/spec/index.html new file mode 100644 index 0000000..de1968a --- /dev/null +++ b/dist/spec/index.html @@ -0,0 +1,4231 @@ + + + + + Trusted Types + + + + + + + + + + + + + + + + + + +
+

+

Trusted Types

+

Editor’s Draft,

+
+ More details about this document +
+
+
This version: +
https://w3c.github.io/trusted-types/dist/spec/ +
Latest published version: +
https://www.w3.org/TR/trusted-types/ +
Feedback: +
public-webappsec@w3.org with subject line “[trusted-types] … message topic …” (archives) +
GitHub +
Inline In Spec +
Editor: +
(Google LLC) +
Former Editor: +
(Google LLC) +
Test Suite: +
https://wpt.fyi/results/trusted-types/ +
+
+
+
+ +
+
+
+

Abstract

+

An API that allows applications to lock down powerful APIs to only accept non-spoofable, typed values in place of strings to prevent vulnerabilities caused by using these APIs with attacker-controlled inputs.

+
+

Status of this document

+
+

This is a public copy of the editors’ draft. + It is provided for discussion only and may change at any moment. + Its publication here does not imply endorsement of its contents by W3C. + Don’t cite this document other than as work in progress.

+

Changes to this document may be tracked at https://github.com/w3c/webappsec.

+

The (archived) public mailing list public-webappsec@w3.org (see instructions) + is preferred for discussion of this specification. + When sending e-mail, + please put the text “trusted-types” in the subject, + preferably like this: + “[trusted-types] …summary of comment…

+

This document was produced by the Web Application Security Working Group.

+

This document was produced by a group operating under + the W3C Patent Policy. + W3C maintains a public list of any patent disclosures made in connection with the deliverables of the group; + that page also includes instructions for disclosing a patent. + An individual who has actual knowledge of a patent which the individual believes contains Essential Claim(s) must disclose the information in accordance with section 6 of the W3C Patent Policy.

+

This document is governed by the 03 November 2023 W3C Process Document.

+

+
+
+ +
+
+ Tests + +
+

1. Introduction

+

This section is not normative.

+

Certain classes of vulnerabilities occur when a web application +takes a value from an attacker-controlled source (e.g. the +document URL parameter, or postMessage channel) and passes that value, +without appropriate sanitization to one of the injection sinks - various Web API functions with +powerful capabilities.

+

These types of issues are traditionally difficult to prevent. +Applications commonly call those injection sinks with attacker-controlled +values without authors realizing it, since it’s not clear if the +input was attacker-controlled when invoking the injection sink. +Due to the dynamic nature of JavaScript it’s also difficult to ascertain +that such pattern is not present in a given program. It is often missed +during manual code reviews, and automated code analysis. As an example, +if aString contains untrusted data, foo[bar] = aString is a statement +that potentially can trigger a vulnerability, depending on a value +of foo and bar.

+

This document focuses on preventing DOM-Based Cross-Site Scripting +that occurs when attacker-controlled data reaches § 2.1.1 DOM XSS injection sinks, as that eventually causes execution of the +script payload controlled by the attacker. DOM XSS is prevalent in the +web applications as there are over 60 different +injection sinks (e.g. Element.innerHTML, or Location.href setters).

+

This document defines Trusted Types - an API that allows applications +to lock down injection sinks to only accept non-spoofable, typed values +in place of strings. These values can in turn only be created from +application-defined policies, allowing the authors to define rules +guarding dangerous APIs, reducing the attack surface to small, isolated parts +of the web application codebase, which are substantially easier to safeguard, +monitor and review.

+

1.1. Goals

+ +

1.2. Non-goals

+ +

1.3. Use cases

+ +

2. Framework

+

2.1. Injection sinks

+

This section is not normative.

+

An injection sink is a powerful Web API function that should only +be called with trusted, validated or appropriately sanitized input. +Calling the injection sink with attacker-controlled (i.e. injected) inputs +has undesired consequences and is considered a security vulnerability.

+

Note: The exact list of injection sinks covered by this document is defined in § 4 Integrations.

+

It’s difficult to determine if a given application contains such a +vulnerability (e.g. if it is vulnerable to DOM XSS) only by analyzing +the invocations of injection sinks, as their inputs (usually strings) +do not carry the information about their provenance. For example, while +the application might intentionally call eval() with dynamically created +inputs (e.g. for code obfuscation purposes), calling eval() on strings +supplied by the attacker is definitely a security vulnerability - but +it’s not easy to distinguish one from the other.

+

This document organizes the injection sinks into groups, based on the +capabilities that sinks in a given group have. Enforcement for groups is controlled via trusted-types-sink-group values.

+

2.1.1. DOM XSS injection sinks

+

This section is not normative.

+

DOM XSS injection sinks evaluate an input string value in a way that could +result in DOM XSS if that value is untrusted.

+

Examples include:

+ +

Since HTML parsers can create arbitrary elements, including scripts, and set arbitrary attributes, +DOM XSS injection sinks also include HTML parsing sinks:

+ +

Guarding DOM XSS injection sinks is controlled by the trusted-types-sink-group named 'script'.

+

2.2. Trusted Types

+

To allow the authors to control values reaching injection sinks, +we introduce § 2.2 Trusted Types. The following list of Trusted Types indicating that a given value is +trusted by the authors to be used with an injection sink in a certain context.

+

Note: Trusted in this context signifies the fact that the application author +is confident that a given value can be safely used with an injection sink - she trusts it does not introduce a vulnerability. That does not imply that the +value is indeed safe.

+

Note: This allows the authors to specify the intention when creating a given +value, and the user agents to introduce checks based on the type of +such value to preserve the authors' intent. For example, if +authors intend a value to be used as an HTML snippet, an attempt to +load a script from that value would fail.

+

Note: All Trusted Types wrap over an immutable string, specified when the +objects are created. These objects are unforgeable in a sense that +there is no JavaScript-exposed way to replace the inner string value +of a given object - it’s stored in an internal slot with no setter +exposed.

+

Note: All Trusted Types stringifiers return the inner string value. +This makes it easy to incrementally migrate the application code into using +Trusted Types in place of DOM strings (it’s possible to start +producing types in parts of the application, while still using and +accepting strings in other parts of the codebase). In that sense, +Trusted Types are backwards-compatible with the regular DOM APIs.

+

2.2.1. TrustedHTML

+

The TrustedHTML interface represents a string that a developer can +confidently insert into an injection sink that will render it as HTML. +These objects are immutable +wrappers around a string, constructed via a TrustedTypePolicy's createHTML method.

+
[Exposed=(Window,Worker)]
+interface TrustedHTML {
+  stringifier;
+  DOMString toJSON();
+};
+
+

TrustedHTML objects have an associated string data. +The value is set when the object is created, and will never change during its lifetime.

+

toJSON() method steps and the stringification behavior steps of a +TrustedHTML object are to return the associated data value.

+

2.2.2. TrustedScript

+

The TrustedScript interface represents a string with an uncompiled +script body that a developer can confidently pass into an injection sink that might lead to executing that script. +These objects are immutable wrappers +around a string, constructed via a TrustedTypePolicy's createScript method.

+
[Exposed=(Window,Worker)]
+interface TrustedScript {
+  stringifier;
+  DOMString toJSON();
+};
+
+

TrustedScript objects have an associated string data. +The value is set when the object is created, and will never change during its lifetime.

+

toJSON() method steps and the stringification behavior steps of a +TrustedScript object are to return the associated data value.

+

2.2.3. TrustedScriptURL

+

The TrustedScriptURL interface represents a string that a developer +can confidently pass into an injection sink that will parse it as a URL of +an external script resource. +These objects are immutable wrappers around a +string, constructed via a TrustedTypePolicy's createScriptURL method.

+
[Exposed=(Window,Worker)]
+interface TrustedScriptURL {
+  stringifier;
+  USVString toJSON();
+};
+
+

TrustedScriptURL objects have an associated string data. +The value is set when the object is created, and will never change during its lifetime.

+

toJSON() method steps and the stringification behavior steps of a +TrustedScriptURL object are to return the associated data value.

+

2.3. Policies

+

Trusted Types can only be created via user-defined +and immutable policies that define rules for converting a string into +a given Trusted Type object. Policies allows the authors to specify custom, +programmatic rules that Trusted Types must adhere to.

+
+ Authors may define a +policy that will sanitize an HTML string, allowing only a subset of +tags and attributes that are known not to cause JavaScript +execution. Any TrustedHTML object created through this policy can then +be safely used in the application, and e.g. passed to innerHTML setter - even if the input value was controlled by the attacker, the +policy rules neutralized it to adhere to policy-specific +contract. +
const sanitizingPolicy = trustedTypes.createPolicy('sanitize-html', {
+  createHTML: (input) => myTrustedSanitizer(input, { superSafe: 'ok'}),
+});
+
+myDiv.innerHTML = sanitizingPolicy.createHTML(untrustedValue);
+
+
+

Note: Trusted Type objects wrap values that are explicitly trusted by +the author. As such, creating a Trusted Type object instance becomes a de +facto injection sink, and hence code that creates a Trusted Type +instances is security-critical. To allow for strict control over Trusted Type +object creation we don’t expose the constructors of those +directly, but require authors to create them via policies.

+

Multiple policies can be created in a given Realm, allowing the +applications to define different rules for different parts of the +codebase.

+
+ Library initialized with a policy allowing it to load additional scripts from +a given host. +
const cdnScriptsPolicy = trustedTypes.createPolicy('cdn-scripts', {
+  createScriptURL(url) {
+    const parsed = new URL(url, document.baseURI);
+    if (parsed.origin == 'https://mycdn.example') {
+      return url;
+    }
+    throw new TypeError('invalid URL');
+  },
+});
+
+myLibrary.init({policy: cdnScriptsPolicy});
+
+
+

Note: Trusted Type objects can only be created via policies. If enforcement is enabled, only the policy code can trigger an action +of an injection sink and hence call-sites of the policies' create* functions are the only security-sensitive code in the entire program +with regards to the actions of the injection sinks. +Only this typically small subset of the entire code base needs to be +security-reviewed - there’s no need to monitor or review +the injection sinks themselves, as User Agents enforce that +those sinks will only accept matching Trusted Type objects, and these in turn +can only be created via policies.

+

The createPolicy function returns a policy object which create* functions +will create Trusted Type objects after applying the policy +rules.

+

Note: While it’s safe to freely use a policy that sanitizes its input anywhere in the application, +there might be a need to create lax policies to be used internally, and only to be +called with author-controlled input. For example, a client-side HTML +templating library, an HTML sanitizer library, or a JS asynchronous +code plugin loading subsystem each will likely need full control over +HTML or URLs. The API design facilitates that - each policy may only +be used if the callsite can obtain a reference to the policy (a return +value from createPolicy()). As such, policy +references can be treated as capabilities, +access to which can be controlled using JavaScript techniques +(e.g. via closures, internal function variables, or modules).

+
+ Unsafe no-op policy reachable only from within a single code block to ascertain +that it’s called only with no attacker-controlled values. +
(function renderFootnote() {
+  const unsafePolicy = trustedTypes.createPolicy('html', {
+    createHTML: input => input,
+  });
+  const footnote = await fetch('/footnote.html').then(r => r.text());
+  footNote.innerHTML = unsafePolicy.createHTML(footnote);
+})();
+
+
+

2.3.1. TrustedTypePolicyFactory

+

TrustedTypePolicyFactory creates policies and verifies that Trusted Type object instances +were created via one of the policies.

+

Note: This factory object is exposed to JavaScript through trustedTypes property +on the global object - see § 4.3.1 Extensions to the WindowOrWorkerGlobalScope interface.

+
[Exposed=(Window,Worker)] interface TrustedTypePolicyFactory {
+    TrustedTypePolicy createPolicy(
+        DOMString policyName, optional TrustedTypePolicyOptions policyOptions = {});
+    boolean isHTML(any value);
+    boolean isScript(any value);
+    boolean isScriptURL(any value);
+    readonly attribute TrustedHTML emptyHTML;
+    readonly attribute TrustedScript emptyScript;
+    DOMString? getAttributeType(
+        DOMString tagName,
+        DOMString attribute,
+        optional DOMString? elementNs = "",
+        optional DOMString? attrNs = "");
+    DOMString? getPropertyType(
+        DOMString tagName,
+        DOMString property,
+        optional DOMString? elementNs = "");
+    readonly attribute TrustedTypePolicy? defaultPolicy;
+};
+
+

A TrustedTypePolicyFactory object has an associated TrustedTypePolicy default policy. +Its value is initially null.

+

A TrustedTypePolicyFactory object has an associated ordered set of strings created policy names. +Its value is initially « ».

+
+
+
createPolicy(policyName, policyOptions) +
+

Creates a policy object that will implement the rules +passed in the TrustedTypePolicyOptions policyOptions object. +The allowed policy names may be restricted by Content Security Policy. +If the policy name is not on the allowlist defined in the trusted-types CSP directive, +the policy creation fails with a TypeError. +Also, if unique policy names are enforced (i.e. 'allow-duplicates' is not used), +and createPolicy is called more than once with any given policyName, +policy creation fails with a TypeError.

+
+ +
// HTTP Response header: Content-Security-Policy: trusted-types foo
+trustedTypes.createPolicy("foo", {}); // ok.
+trustedTypes.createPolicy("bar", {}); // throws - name not on the allowlist.
+trustedTypes.createPolicy("foo", {}); // throws - duplicate name.
+
+
+

Returns the result of executing a Create a Trusted Type Policy algorithm, +with the following arguments:

+
+
factory +
this value +
policyName +
policyName +
options +
policyOptions +
global +
this value’s relevant global object +
+
+ +
const myPolicy = trustedTypes.createPolicy('myPolicy', {
+  // This security-critical code needs a security review;
+  // a flaw in this code could cause DOM XSS.
+  createHTML(input) { return aSanitizer.sanitize(input) },
+  createScriptURL(input) {
+    const u = new URL(dirty, document.baseURI);
+    if (APPLICATION_CONFIG.scriptOrigins.includes(u.origin)) {
+      return u.href;
+    }
+    throw new Error('Cannot load scripts from this origin');
+  },
+});
+
+document.querySelector("#foo").innerHTML = myPolicy.createHTML(aValue);
+scriptElement.src = myPolicy.createScriptURL(
+    'https://scripts.myapp.example/script.js');
+
+
+
isHTML(value) +
+

Returns true if value is an instance of TrustedHTML and has an associated data value set, false otherwise.

+

Note: is* functions are used to check if a given object is truly a legitimate Trusted Type object (i.e. it was created via one of the configured +policies). This is to be able to detect a forgery of the objects via +e.g. Object.create or prototype chains manipulation.

+
+ +
const html = policy.createHTML('<div>');
+trustedTypes.isHTML(html); // true
+
+const fake = Object.create(TrustedHTML.prototype);
+trustedTypes.isHTML(fake); // false
+
+trustedTypes.isHTML("<div>plain string</div>"); // false
+
+
+
isScript(value) +
+

Returns true if value is an instance of TrustedScript and has an associated data value set, false otherwise.

+
isScriptURL(value) +
+

Returns true if value is an instance of TrustedScriptURL and has an associated data value set, false otherwise.

+
getPropertyType(tagName, property, elementNs) +
+

Allows the authors to check if a Trusted Type is required for a given Element's +property (IDL attribute).

+

This function returns the result of the following algorithm:

+
    +
  1. +

    Set localName to tagName in ASCII lowercase.

    +
  2. +

    If elementNs is an empty string, set elementNs to HTML namespace.

    +
  3. +

    Let interface be the element interface for localName and elementNs.

    +
  4. +

    Let expectedType be null.

    +
  5. +

    Find the row in the following table, where the first column is "*" or interface’s name, and property is in the second column. +If a matching row is found, set expectedType to the value of the third column.

    + + + + + + + + + + + +
    Element + Property name + TrustedType +
    HTMLIFrameElement + "srcdoc" + TrustedHTML +
    HTMLScriptElement + "innerText" + TrustedScript +
    HTMLScriptElement + "src" + TrustedScriptURL +
    HTMLScriptElement + "text" + TrustedScript +
    HTMLScriptElement + "textContent" + TrustedScript +
    "*" + "innerHTML" + TrustedHTML +
    "*" + "outerHTML" + TrustedHTML +
    +
  6. +

    Return expectedType.

    +
+
+ +
trustedTypes.getPropertyType('div', 'innerHTML'); // "TrustedHTML"
+trustedTypes.getPropertyType('foo', 'bar'); // null
+
+
+
getAttributeType(tagName, attribute, elementNs, attrNs) +
+

Allows the authors to check if, (and if so, which) Trusted Type is required +for a given Element's content attribute, such that later on the call +to Element.setAttribute passes the correct argument type.

+

This function returns the result of the following algorithm:

+
    +
  1. +

    Set localName to tagName in ASCII lowercase.

    +
  2. +

    Set attribute to attribute in ASCII lowercase.

    +
  3. +

    If elementNs is an empty string, set elementNs to HTML namespace.

    +
  4. +

    If attrNs is an empty string, set attrNs to null.

    +
  5. +

    Let interface be the element interface for localName and elementNs.

    +
  6. +

    Let expectedType be null.

    +
  7. +

    Set attributeData to the result of Get Trusted Type data for attribute algorithm, with the following arguments:

    +
      +
    • +

      interface as element

      +
    • +

      attribute

      +
    • +

      attrNs

      +
    +
  8. +

    If attributeData is not null, then set expectedType to the value of the third member of attributeData.

    +
  9. +

    Return expectedType.

    +
+
+ +
trustedTypes.getAttributeType('script', 'src'); // "TrustedScriptURL"
+trustedTypes.getAttributeType('foo', 'bar'); // null
+
+
+
+
+
+
+
emptyHTML, of type TrustedHTML, readonly +
+

is a TrustedHTML object with its data value set to an empty string.

+
+
+ +
anElement.innerHTML = trustedTypes.emptyHTML; // no need to create a policy
+
+
+
+
emptyScript, of type TrustedScript, readonly +
+

is a TrustedScript object with its data value set to an empty string.

+
+

Note: This object can be used to detect if the runtime environment has § 4.5.6 Support for dynamic code compilation. While native Trusted Types implementation can +support eval(TrustedScript), it is impossible for a polyfill to emulate that, as +eval(TrustedScript) will return its input without unwrapping and evaluating the code.

+
+ +
// With native Trusted Types support eval(trustedTypes.emptyScript) will execute and return falsy undefined.
+// Without it, eval(trustedTypes.emptyScript) will return a truthy Object.
+const supportsTS = !eval(trustedTypes.emptyScript);
+
+eval(supportsTS ? myTrustedScriptObj : myTrustedScriptObj.toString());
+
+
+
+
defaultPolicy, of type TrustedTypePolicy, readonly, nullable +
+

Returns the value of default policy.

+
+
+ +
trustedTypes.defaultPolicy === null;  // true
+const dp = trustedTypes.createPolicy('default', {});
+trustedTypes.defaultPolicy === dp;  // true
+
+
+
+

2.3.2. TrustedTypePolicy

+

Policy objects implement a TrustedTypePolicy interface and define a +group of functions creating Trusted Type objects. +Each of the create* functions converts a string value to a given Trusted Type variant, or +throws a TypeError if a conversion of a given value is disallowed.

+
[Exposed=(Window,Worker)]
+interface TrustedTypePolicy {
+  readonly attribute DOMString name;
+  TrustedHTML createHTML(DOMString input, any... arguments);
+  TrustedScript createScript(DOMString input, any... arguments);
+  TrustedScriptURL createScriptURL(DOMString input, any... arguments);
+};
+
+

Each policy has a name.

+

Each TrustedTypePolicy object has an associated TrustedTypePolicyOptions options object, describing the actual behavior of the policy.

+
+
+
createHTML(input, ...arguments) +
+

Returns the +result of executing the Create a Trusted Type algorithm, with the +following arguments:

+
+
policy +
this value +
trustedTypeName +
"TrustedHTML" +
value +
input +
arguments +
arguments +
+
createScript(input, ...arguments) +
+

Returns the +result of executing the Create a Trusted Type algorithm, with the +following arguments:

+
+
policy +
this value +
trustedTypeName +
"TrustedScript" +
value +
input +
arguments +
arguments +
+
createScriptURL(input, ...arguments) +
+

Returns the +result of executing the Create a Trusted Type algorithm, with the +following arguments:

+
+
policy +
this value +
trustedTypeName +
"TrustedScriptURL" +
value +
input +
arguments +
arguments +
+
+
+

2.3.3. TrustedTypePolicyOptions

+

This dictionary holds author-defined functions for converting string +values into trusted values. These functions do not create Trusted Type object instances directly - this behavior is provided by TrustedTypePolicy.

+
dictionary TrustedTypePolicyOptions {
+   CreateHTMLCallback createHTML;
+   CreateScriptCallback createScript;
+   CreateScriptURLCallback createScriptURL;
+};
+callback CreateHTMLCallback = DOMString? (DOMString input, any... arguments);
+callback CreateScriptCallback = DOMString? (DOMString input, any... arguments);
+callback CreateScriptURLCallback = USVString? (DOMString input, any... arguments);
+
+

2.3.4. Default policy

+

This section is not normative.

+

One of the policies, the policy with a name "default", is special; +When an injection sink is passed a string (instead of a +Trusted Type object), this policy will be implicitly called by +the user agent with the non trusted string value, Trusted Type of the sink and +the sink type, respectively.

+

This allows the application to define a fallback behavior to use instead of +causing a violation. The intention is to allow the applications to recover from +an unexpected data flow, and sanitize the +potentially attacker-controlled string "as a last resort", or reject a value +if a safe value cannot be created. Errors thrown from within a policy are +propagated to the application.

+

If the default policy doesn’t exist, or if its appropriate create* function +returns null or undefined, it will cause a CSP violation. In the +enforcing mode, an error will be thrown, but in report-only the original value +passed to the default policy will be used.

+

Note: This optional behavior allows for introducing Trusted Type enforcement to applications that are still using legacy code that uses injection sinks. +Needless to say, this policy should +necessarily be defined with very strict rules not to bypass the security +restrictions in unknown parts of the application. In an extreme +case, a lax, no-op default policy defeats all the benefits of using Trusted Types +to protect access to injection sinks. If possible, +authors should resort to a default policy in a transitional period +only, use it to detect and rewrite their dependencies that use injection +sinks unsafely and eventually phase out the usage of the default policy entirely.

+

Note: See § 3.4 Get Trusted Type compliant string for details on how +the default policy is applied.

+
+ +
// Content-Security-Policy: trusted-types default; require-trusted-types-for 'script'
+
+trustedTypes.createPolicy('default', {
+  createScriptURL: (value, type, sink) => {
+    console.log("Please refactor.");
+    return value + '?default-policy-used&type=' + encodeURIComponent(type) +
+          '&sink=' + encodeURIComponent(sink);
+  }
+});
+
+aScriptElement.src = "https://cdn.example/script.js";
+// Please refactor.
+console.log(aScriptElement.src);
+// https://cdn.example/script.js?default-policy-used&type=TrustedScriptURL&sink=HTMLScriptElement%20src
+
+
+

2.4. Enforcement

+

Note: Enforcement is the process of checking that a value +has an appropriate type before it reaches an injection sink.

+

The JavaScript API that allows authors to create policies and Trusted Types objects from them is always +available (via trustedTypes). Since injection sinks stringify their security sensitive +arguments, and Trusted Type objects stringify to their inner string values, this allows the authors +to use Trusted Types in place of strings.

+

To secure the access to injection sinks, on top of the JavaScript code using the Trusted Types, +the user agent needs to enforce them i.e. assert that the injection sinks from a given group are never called with string values, and Trusted Type values are used instead. This section describes how authors +may control this enforcing behavior.

+

Authors may also control their policies by specifying rules around policy creation.

+

2.4.1. Content Security Policy

+

Applications may control Trusted Type enforcement via configuring a Content Security Policy. This document defines new directives that correspond to Trusted Types rules. +The require-trusted-types-for directive specifies the injection sinks groups, for which the types should be required. The trusted-types directive controls how policies can be created.

+

Note: Using CSP mechanisms allows the authors to prepare their application for enforcing Trusted Types +via using the Content-Security-Policy-Report-Only HTTP Response header.

+

Note: Most of the enforcement rules are defined as modifications of the +algorithms in other specifications, see § 4 Integrations.

+

3. Algorithms

+

3.1. Create a Trusted Type Policy

+

To create a TrustedTypePolicy, given a TrustedTypePolicyFactory (factory), +a string (policyName), TrustedTypePolicyOptions dictionary (options), and a global object (global) run these steps:

+
    +
  1. +

    Let allowedByCSP be the result of executing Should Trusted Type policy +creation be blocked by Content Security Policy? algorithm with global, policyName and factory’s created policy names value.

    +
  2. +

    If allowedByCSP is "Blocked", throw a TypeError and abort further steps.

    +
  3. +

    If policyName is default and the factory’s default policy value is not null, throw a TypeError and abort further steps.

    +
  4. +

    Let policy be a new TrustedTypePolicy object.

    +
  5. +

    Set policy’s name property value to policyName.

    +
  6. +

    Let policyOptions be a new TrustedTypePolicyOptions object.

    +
  7. +

    Set policyOptions createHTML property to optionscreateHTML property value.

    +
  8. +

    Set policyOptions createScript property to optionscreateScript property value.

    +
  9. +

    Set policyOptions createScriptURL property to optionscreateScriptURL property value.

    +
  10. +

    Set policy’s options value to policyOptions.

    +
  11. +

    If the policyName is default, set the factory’s default policy value to policy.

    +
  12. +

    Append policyName to factory’s created policy names.

    +
  13. +

    Return policy.

    +
+

3.2. Create a Trusted Type

+

Given a TrustedTypePolicy policy, a type name trustedTypeName, +a string value and a list arguments, execute the following steps:

+
    +
  1. +

    Let policyValue be the result of executing Get Trusted Type policy value with the same arguments as this algorithm and additionally true as throwIfMissing.

    +
  2. +

    If the algorithm threw an error, rethrow the error and abort the following steps.

    +
  3. +

    Let dataString be the result of stringifying policyValue.

    +
  4. +

    Return a new instance of an interface with a type +name trustedTypeName, with its associated data value set to dataString.

    +
+

3.3. Get Trusted Type policy value

+

Given a TrustedTypePolicy policy, a type name trustedTypeName, +a string value, a list arguments, and a boolean throwIfMissing, execute the following steps:

+
    +
  1. +

    Let functionName be a function name for the given trustedTypeName, +based on the following table:

    + + + + + + +
    Function name + Trusted Type name +
    "createHTML" + "TrustedHTML" +
    "createScript" + "TrustedScript" +
    "createScriptURL" + "TrustedScriptURL" +
    +
  2. +

    Let function be the value of the property in policy’s options named functionName.

    +
  3. +

    If function is null, then:

    +
      +
    1. +

      If throwIfMissing throw a TypeError.

      +
    2. +

      Else return null.

      +
    +
  4. +

    Let policyValue be the result of invoking function with value as a first argument, items of arguments as subsequent arguments, +and callback **this** value set to null, rethrowing any exceptions.

    +
  5. +

    Return policyValue.

    +
+

3.4. Get Trusted Type compliant string

+

This algorithm will return a string that can be used with an injection sink, optionally unwrapping it from a matching Trusted Type. +It will ensure that the Trusted Type enforcement rules were respected.

+

Given a TrustedType type (expectedType), a global object (global), TrustedType or a string (input), a string (sink) and a string (sinkGroup), run these steps:

+
    +
  1. +

    If input has type expectedType, return stringified input and abort these steps.

    +
  2. +

    Let requireTrustedTypes be the result of executing Does sink type require trusted types? algorithm, +passing global, and sinkGroup.

    +
  3. +

    If requireTrustedTypes is false, return stringified input and abort these steps.

    +
  4. +

    Let convertedInput be the result of executing Process value with a default policy with the same arguments as this algorithm.

    +
  5. +

    If the algorithm threw an error, rethrow the error and abort the following steps.

    +
  6. +

    If convertedInput is null or undefined, execute the following steps:

    +
      +
    1. +

      Let disposition be the result of executing Should sink type mismatch violation be blocked by Content Security Policy? algorithm, +passing global, stringified input as source, sinkGroup and sink.

      +
    2. +

      If disposition is “Allowed”, return stringified input and abort further steps.

      +

      Note: This step assures that the default policy rejection will be reported, but ignored in a report-only mode.

      +
    3. +

      Throw a TypeError and abort further steps.

      +
    +
  7. +

    Assert: convertedInput has type expectedType.

    +
  8. +

    Return stringified convertedInput.

    +
+

3.5. Process value with a default policy

+

This algorithm routes a value to be assigned to an injection sink through a default policy, should one exist.

+

Given a TrustedType type (expectedType), a global object (global), TrustedType or a string (input), and a string (sink), run these steps:

+
    +
  1. +

    Let defaultPolicy be the value of global’s trusted type policy factory's default policy.

    +
  2. +

    Let policyValue be the result of executing Get Trusted Type policy value, with the following arguments:

    +
      +
    • +

      defaultPolicy as policy

      +
    • +

      stringified input as value

      +
    • +

      expectedType’s type name as trustedTypeName

      +
    • +

      « trustedTypeName, sink » as arguments

      +
    • +

      false as throwIfMissing

      +
    +
  3. +

    If the algorithm threw an error, rethrow the error and abort the following steps.

    +
  4. +

    If policyValue is null or undefined, return policyValue.

    +
  5. +

    Let dataString be the result of stringifying policyValue.

    +
  6. +

    Return a new instance of an interface with a type +name trustedTypeName, with its associated data value set to dataString.

    +
+

3.6. Prepare the script text

+

Given an HTMLScriptElement (script), this algorithm performs the following steps:

+
    +
  1. +

    If script’s script text value is not equal to its child text content, +set script’s script text to the result of executing Get Trusted Type compliant string, with the following arguments:

    + +

    If the algorithm threw an error, rethrow the error.

    +
+

3.7. Get Trusted Types-compliant attribute value

+ To get Trusted Types-compliant attribute value on Attr attribute with Element element and TrustedType or a string newValue, perform the following steps: +
    +
  1. +

    Set attributeData to the result of Get Trusted Type data for attribute algorithm, with the following arguments:

    +
      +
    • +

      element

      +
    • +

      attribute’s local name as attribute

      +
    • +

      attribute’s namespace as attributeNs

      +
    +
  2. +

    If attributeData is null, then:

    +
      +
    1. +

      If newValue is a string, return newValue.

      +
    2. +

      Assert: newValue is TrustedHTML or TrustedScript or TrustedScriptURL.

      +
    3. +

      Return value’s associated data.

      +
    +
  3. +

    Let expectedType be the value of the third member of attributeData.

    +
  4. +

    Let sink be the value of the fourth member of attributeData.

    +
  5. +

    Return the result of executing Get Trusted Type compliant string with the following arguments:

    + +
+

If the algorithm threw an error, rethrow the error.

+

3.8. Get Trusted Type data for attribute

+ To Get Trusted Type data for attribute given element, attribute, attributeNs, perform the following steps: +

The event handler content attribute concept used below is ambiguous. This spec needs a better mechanism to identify event handler attributes. See https://github.com/w3c/trusted-types/issues/520.

+
    +
  1. +

    Let data be null.

    +
  2. +

    If attributeNs is null, and attribute is the name of an event handler content attribute, then:

    +
      +
    1. +

      Return (Element, null, attribute, TrustedScript, "Element " + attribute).

      +
    +
  3. +

    Find the row in the following table, where element is in the first column, attributeNs is in the second column, +and attribute is in the third column. +If a matching row is found, set data to that row.

    + + + + + + + + +
    Element + Attribute namespace + Attribute local name + TrustedType + Sink +
    HTMLIFrameElement + null + "srcdoc" + TrustedHTML + "HTMLIFrameElement srcdoc" +
    HTMLScriptElement + null + "src" + TrustedScriptURL + "HTMLScriptElement src" +
    SVGScriptElement + null + "href" + TrustedScriptURL + "SVGScriptElement href" +
    SVGScriptElement + XLink namespace + "href" + TrustedScriptURL + "SVGScriptElement href" +
    +
  4. +

    Return data.

    +
+

4. Integrations

+
typedef [StringContext=TrustedHTML] DOMString HTMLString;
+typedef [StringContext=TrustedScript] DOMString ScriptString;
+typedef [StringContext=TrustedScriptURL] USVString ScriptURLString;
+typedef (TrustedHTML or TrustedScript or TrustedScriptURL) TrustedType;
+
+

4.1. Integration with WebIDL

+

4.2. [StringContext]

+

See https://github.com/whatwg/webidl/pull/1392.

+

4.3. Integration with HTML

+

Window and Worker objects have a trusted type policy factory, +which is a TrustedTypePolicyFactory object.

+

4.3.1. Extensions to the WindowOrWorkerGlobalScope interface

+

This document extends the WindowOrWorkerGlobalScope interface defined by HTML:

+
partial interface mixin WindowOrWorkerGlobalScope {
+  readonly attribute TrustedTypePolicyFactory trustedTypes;
+};
+
+

The trustedTypes getter steps are to return this's relevant global object's trusted +type policy factory.

+

4.3.2. Enforcement for scripts

+

This document modifies how HTMLScriptElement child text content can be set to allow applications to control dynamically created scripts. It does so by +adding the innerText and textContent attributes directly on HTMLScriptElement. The behavior of the attributes remains the same +as in their original counterparts, apart from the additional behavior of calling Get Trusted Type compliant string.

+

Note: Using these IDL attributes is the recommended way of dynamically setting the URL or a text of a script. Manipulating attribute nodes or text nodes directly will call a default policy on the final value when the script is prepared.

+
partial interface HTMLScriptElement {
+ [CEReactions] attribute ([LegacyNullToEmptyString] DOMString or TrustedScript) innerText;
+ [CEReactions] attribute (DOMString or TrustedScript)? textContent;
+ [CEReactions] attribute (USVString or TrustedScriptURL) src;
+ [CEReactions] attribute (DOMString or TrustedScript) text;
+};
+
+
4.3.2.1. Slots with trusted values
+

This document modifies HTMLScriptElements. Each script has:

+
+
an associated string script text. +
+

A string, containing the body of the script to execute that was set +through a compliant sink. Equivalent to script’s child text content. Initially an empty string.

+
+
4.3.2.2. The innerText IDL attribute
+

The innerText setter steps are:

+
    +
  1. +

    Let value be the result of calling Get Trusted Type compliant string with TrustedScript, this's relevant global object, the given value, HTMLScriptElement innerText, and script.

    +
  2. +

    Set this's script text value to value.

    +
  3. +

    Run set the inner text steps with this and value.

    +
+

The innerText getter steps are:

+
    +
  1. +

    Return the result of running get the text steps with this.

    +
+
4.3.2.3. The textContent IDL attribute
+

The textContent setter steps are to, if the given value is null, act as if it was the +empty string instead, and then do as described below:

+
    +
  1. +

    Let value be the result of calling Get Trusted Type compliant string with TrustedScript, this's relevant global object, the given value, HTMLScriptElement textContent, and script.

    +
  2. +

    Set this's script text value to value.

    +
  3. +

    Run set text content with this and value.

    +
+

The textContent getter steps are:

+
    +
  1. +

    Return the result of running get text content with this.

    +
+
4.3.2.4. The text IDL attribute
+

Update the text setter steps algorithm as follows.

+
    +
  1. + Let value be the result of calling Get Trusted Type compliant string with TrustedScript, this's relevant global object, the given value, HTMLScriptElement text, and script. +
  2. + Set this's script text value to the given value. +
  3. +

    String replace all with the given value within this.

    +
+
4.3.2.5. The src IDL attribute
+

The src setter steps are:

+
    +
  1. + Let value be the result of calling Get Trusted Type compliant string with TrustedScriptURL, this's relevant global object, the given value, HTMLScriptElement src, and script. +
  2. + Set this's src content attribute to value. +
+
4.3.2.6. Slot value verification
+

The first few steps of the prepare the script element algorithm are modified as follows:

+
    +
  1. +

    If el’s already started is true, then return.

    +
  2. +

    Let parser document be el’s parser document.

    +
  3. +

    Set el’s parser document to null.

    +

    This is done so that if parser-inserted script elements fail to run + when the parser tries to run them, e.g. because they are empty or specify an unsupported + scripting language, another script can later mutate them and cause them to run again.

    +
  4. +

    If parser document is non-null and el does not have an async attribute, then set el’s force async to true.

    +

    This is done so that if a parser-inserted script element fails to + run when the parser tries to run it, but it is later executed after a script dynamically + updates it, it will execute in an async fashion even if the async attribute isn’t set.

    +
  5. + +

    Execute the Prepare the script text algorithm on el. If that algorithm threw an error, then return.

    +
    +
  6. +

    + Let source text be el’s + child text content. + script text value. +

    +
  7. ... +
+

4.3.3. Enforcement in timer functions

+

Note: See https://github.com/whatwg/html/pull/10348 which upstreams this integration.

+

4.3.4. HostEnsureCanCompileStrings

+

+ JavaScript contains an implementation-defined HostEnsureCanCompileStrings(realm, + parameterStrings, bodyString, compilationType, parameterArgs, bodyArg + ) +abstract operation. User agents must use the following implementation: +

+
    +
  1. +

    + Perform ? EnsureCSPDoesNotBlockStringCompilation(realm, + parameterStrings, bodyString, compilationType, parameterArgs, bodyArg + ). +

    +
+

4.3.5. HostGetCodeForEval

+

JavaScript contains an implementation-defined HostGetCodeForEval(argument) +abstract operation. User agents must use the following implementation:

+
    +
  1. +

    If argument is a TrustedScript object, return the value of its associated data.

    +
  2. +

    Return ~unknown~.

    +
+

4.3.6. Validate the string in context

+

This specification defines the validate the string in context algorithm in HTML § 7.2.1.1 Integration with IDL.

+

When validate the string in context is invoked, with platformObject, value, stringContext, and identifier run these steps:

+
    +
  1. +

    If platformObject’s relevant global object has a trusted type policy factory:

    +
      +
    1. +

      Set sink to the result of concatenating the list « platformObject’s identifier, identifier » with " " as separator.

      +
      + For example, the following annotation and JavaScript code: +
      typedef [StringContext=TrustedHTML] DOMString HTMLString;
      +[ Exposed=Window, HTMLConstructor] interface HTMLIFrameElement : HTMLElement {
      +    attribute HTMLString srcdoc;
      +};
      +
      +
      document.createElement('iframe').srcdoc = foo;
      +document.createElement('iframe').setAttribute('SRCdoc', foo);
      +
      +

      causes the sink value to be "HTMLIFrameElement srcdoc".

      +
      +
    2. +

      Set value to the result of running the Get Trusted Type compliant string algorithm, passing the following arguments:

      +
        +
      • +

        value as input,

        +
      • +

        stringContext as expectedType,

        +
      • +

        sink as sink,

        +
      • +

        'script' as sinkGroup,

        +
      • +

        platformObject’s relevant global object as global.

        +
      +

      Remove hardcoding 'script' when new sink groups are specified.

      +
    3. +

      If an exception was thrown, rethrow exception and abort further steps.

      +
    +
  2. +

    Return value.

    +
+

4.4. Integration with DOM

+

Note: See https://github.com/whatwg/dom/pull/1258 and https://github.com/whatwg/dom/pull/1268 which upstream this integration.

+

4.5. Integration with Content Security Policy

+

4.5.1. require-trusted-types-for directive

+

This document defines require-trusted-types-for - a new Content Security Policy directive.

+

require-trusted-types-for directive configures the Trusted +Types framework for all the injection sinks of certain groups in a current realm. +Specifically, it defines what should be the behavior when a string value is passed to an injection sink of a given group (i.e. should the type-based enforcement be enabled for such sinks).

+

Note: Currently, only the enforcement for § 2.1.1 DOM XSS injection sinks is specified.

+

The syntax for the directive’s name and value is described by the following +ABNF:

+
directive-name = "require-trusted-types-for"
+directive-value = trusted-types-sink-group *( required-ascii-whitespace trusted-types-sink-group)
+trusted-types-sink-group = "'script'"
+
+
+ Enforce Trusted Types at the DOM XSS injection sinks. +
Content-Security-Policy: require-trusted-types-for 'script'
+
+
+
4.5.1.1. require-trusted-types-for Pre-Navigation check
+

Given a request (request), a string navigation type and a policy (policy), this algorithm returns "Blocked" if a navigation violates the require-trusted-types-for directive’s constraints and "Allowed" otherwise. This constitutes the require-trusted-types-for directive’s pre-navigation check:

+

Note: This algorithm assures that the code to be executed by a navigation to a javascript: URL will have to pass through a default policy's createScript function, in addition to all other restrictions imposed by other CSP directives.

+
    +
  1. +

    If request’s url's scheme is not "javascript", return "Allowed" and abort further steps.

    +
  2. +

    Let urlString be the result of running the URL serializer on request’s url.

    +
  3. +

    Let encodedScriptSource be the result of removing the leading "javascript:" from urlString.

    +
  4. +

    Let convertedScriptSource be the result of executing Process value with a default policy algorithm, with the following arguments:

    + +

    If that algorithm threw an error or convertedScriptSource is not a TrustedScript object, return "Blocked" and abort further steps.

    +
  5. +

    Set urlString to be the result of prepending "javascript:" to stringified convertedScriptSource.

    +
  6. +

    Let newURL be the result of running the URL parser on urlString. If the parser returns a failure, return "Blocked" and abort further steps.

    +
  7. +

    Set request’s url to newURL.

    +

    Note: No other CSP directives operate on javascript: URLs in a pre-navigation check. Other directives that check javascript: URLs + will operate on the modified URL later, in the inline check.

    +
  8. +

    Return "Allowed".

    +
+

4.5.2. trusted-types directive

+

This document defines trusted-types - a new Content Security Policy directive. The trusted-types directive controls the creation of Trusted Type policies.

+

The syntax for the directive’s name and value is described by the following +ABNF:

+
directive-name = "trusted-types"
+directive-value = serialized-tt-configuration
+serialized-tt-configuration = ( tt-expression *( required-ascii-whitespace tt-expression ) )
+tt-expression = tt-policy-name  / tt-keyword / tt-wildcard
+tt-wildcard = "*"
+tt-policy-name = 1*( ALPHA / DIGIT / "-" / "#" / "=" / "_" / "/" / "@" / "." / "%")
+tt-keyword = "'allow-duplicates'" / "'none'"
+
+
+ Types are enforced at sinks, and only two policies may be created: “one” and “two”. +
Content-Security-Policy: require-trusted-types-for 'script'; trusted-types one two
+
+
+
+ An empty directive value indicates policies may not be created, +and sinks expect Trusted Type values, i.e. no DOM XSS injection sinks can be used +at all. +
Content-Security-Policy: trusted-types; require-trusted-types-for 'script'
+
+
+

The keyword 'none' may be used to explicitly express the above:

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

Keyword 'allow-duplicates' allows for creating policies with a name that was already used.

+
+ +
Content-Security-Policy: trusted-types foo bar 'allow-duplicates'
+
+
+

If the policy named default is present in the list, it refers to the default policy. +All strings passed to injection sinks will be passed through it instead of being rejected outright.

+
+ +
Content-Security-Policy: trusted-types one two default
+
+
+

4.5.3. Does sink type require trusted types?

+

Given a global object (global), a string (sinkGroup) this algorithm +returns true if the injection sink requires a Trusted Type, and false otherwise.

+
    +
  1. +

    Let result be false.

    +
  2. +

    For each policy in global’s CSP list:

    +
      +
    1. +

      If policy’s directive set does not contain a directive whose name is "require-trusted-types-for", skip to the next policy.

      +
    2. +

      Let directive be the policy’s directive set’s directive whose name +is "require-trusted-types-for"

      +
    3. +

      If directive’s value does not contain a trusted-types-sink-group which is a match +for sinkGroup, skip to the next policy.

      +
    4. +

      Set result to true.

      +
    +
  3. +

    Return result.

    +
+

4.5.4. Should sink type mismatch violation be blocked by Content Security Policy?

+

Given a global object (global), a string (sink), a string (sinkGroup) and a string (source) this algorithm +returns "Blocked" if the injection sink requires a Trusted Type, and "Allowed" otherwise.

+
    +
  1. +

    Let result be "Allowed".

    +
  2. +

    For each policy in global’s CSP list:

    +
      +
    1. +

      If policy’s directive set does not contain a directive whose name is "require-trusted-types-for", skip to the next policy.

      +
    2. +

      Let directive be the policy’s directive set’s directive whose name +is "require-trusted-types-for"

      +
    3. +

      If directive’s value does not contain a trusted-types-sink-group which is a match +for sinkGroup, skip to the next policy.

      +
    4. +

      Let violation be the result of executing Create a violation object for global, policy, and directive on global, policy and "require-trusted-types-for"

      +
    5. +

      Set violation’s resource to "trusted-types-sink".

      +
    6. +

      Let trimmedSource be the substring of source, containing its first 40 characters.

      +
    7. +

      Set violation’s sample to be the result of concatenating the list « sink, trimmedSource « using "|" as a separator.

      +
    8. +

      Execute Report a violation on violation.

      +
    9. +

      If policy’s disposition is "enforce", then set result to "Blocked".

      +
    +
  3. +

    Return result.

    +
+

4.5.5. Should Trusted Type policy creation be blocked by Content Security Policy?

+

Given a global object (global), a string (policyName) and a list of +strings (createdPolicyNames), this algorithm returns "Blocked" if the TrustedTypePolicy should not be created, and "Allowed" otherwise.

+
    +
  1. +

    Let result be "Allowed".

    +
  2. +

    For each policy in global’s CSP list:

    +
      +
    1. +

      Let createViolation be false.

      +
    2. +

      If policy’s directive set does not contain a directive which name is "trusted-types", skip to the next policy.

      +
    3. +

      Let directive be the policy’s directive set’s directive which name +is "trusted-types"

      +
    4. +

      If directive’s value only contains a tt-keyword which +is a match for a value 'none', set createViolation to true.

      +

      Note: Like in other CSP directives, 'none' keyword will be ignored if other keywords or policy names are present.

      +
    5. +

      If createdPolicyNames contains policyName and directive’s value does not contain a tt-keyword which is a match +for a value 'allow-duplicates', set createViolation to true.

      +

      Note: trusted-types policyA policyB 'allow-duplicates' allows authors to create policies with +duplicated names.

      +
    6. +

      If directive’s value does not contain a tt-policy-name, +which value is policyName, and directive’s value does not contain a tt-wildcard, set createViolation to true.

      +

      Note: trusted-types * allows authors to create policies with any unique names. To allow for multiple policies with the same name, use trusted-types * 'allow-duplicates' or don’t set the trusted-types directive at all.

      +
    7. +

      If createViolation is false, skip to the next policy.

      +
    8. +

      Let violation be the result of executing Create a violation object for global, policy, and directive on global, policy and "trusted-types"

      +
    9. +

      Set violation’s resource to "trusted-types-policy".

      +
    10. +

      Set violation’s sample to the substring of policyName, containing its first 40 characters.

      +
    11. +

      Execute Report a violation on violation.

      +
    12. +

      If policy’s disposition is "enforce", then set result to "Blocked".

      +
    +
  3. +

    Return result.

    +
+

4.5.6. Support for dynamic code compilation

+

Note: See https://github.com/w3c/webappsec-csp/pull/659 which upstreams this integration.

+

5. Security Considerations

+

Trusted Types are not intended to protect access to injection sinks in an +actively malicious execution environment. It’s assumed that the application is +written by non-malicious authors; the intent is to prevent developer mistakes +that could result in security bugs, and not to defend against first-party +malicious code actively trying to bypass policy restrictions. Below we enumerate +already identified vectors that remain risky even in environments with enforced +Trusted Types.

+

5.1. Cross-document vectors

+

While the code running in a window in which Trusted Types are enforced cannot +dynamically create nodes that would bypass the policy restrictions, it is +possible that such nodes can be imported or adopted from documents in other +windows, that don’t have the same set of restrictions. In essence - it is +possible to bypass Trusted Types if a malicious author creates a setup in which +a restricted document colludes with an unrestricted one. In an extreme case, the +restricted document might create a Blob from strings and navigate to it.

+

CSP propagation rules (see Content Security Policy 3 § 7.8 CSP Inheriting to avoid bypasses partially address this +issue, as new local scheme documents will inherit the same set of restrictions, +so - for example - script-src restrictions could be used to make sure injections +into Blob contents would not execute scripts. To address this issue +comprehensively, other mechanisms like Origin Policy should be used to ensure that baseline security rules are applied for the whole +origin.

+

5.2. Deprecated features

+

Some long-deprecated and rarely used platform features are not subject to Trusted +Types, and could potentially be used by malicious authors to overcome the +restrictions:

+ +

5.3. Script gadgets

+

While Trusted Types logic is called on many operations that results in creating +DOM trees from string, it should not be treated as a mechanism for guarding all +DOM tree creation in a document. This is important especially in the presence of script gadgets, +where an application reacts to contents of usually benign DOM elements or attributes. +Developers using DOM API directly can trigger such gadgets without using +Trusted Types. However, in order for the gadget to trigger DOM XSS, it needs to +obtain a Trusted Type value via a policy. Authors need to ascertain that the data +passed to Trusted Type policies is indeed trustworthy, if the policy rules don’t +enforce constraints or validate the data themselves.

+

5.4. Best practices for policy design

+

Trusted Types limit the scope of the code that can introduce +vulnerabilities via injection sinks to the implementation of policies. +In this design, insecure policies can still expose injection sinks to untrusted data. +Special emphasis needs to be taken by use policies that are either secure for all +possible inputs, or limit the access to insecure policies, such that they are only +called with non-attacker controlled inputs.

+

As policies are custom JavaScript code, they may be written in a way that heavily +depends on a global state. We advise against this. The policies should +be self-contained as much as possible. All objects that may alter security decisions +a policy makes effectively become the policy, and should be guarded & reviewed +together.

+

Refer to the external document on secure policy design.

+

6. Privacy Considerations

+

The specification may partially observe and alter the behavior of scripts running +within the application, e.g. causing certain operations on injection sinks to fail, or monitoring and changing their effect with a default policy. +However, early-running scripts already have this capability by overriding +appropriate property descriptors.

+

It is possible for the application to report violations of Trusted Types +restrictions. Violation reports would include the trimmed-down payload passed to +the injection sink (40 characters, including the sink name). These feature is +reusing the Content Security Policy reporting mechanisms.

+

7. Implementation Considerations

+

7.1. Vendor-specific Extensions and Addons

+

Restriction imposed by Trusted Types SHOULD +NOT interfere with the operation of user-agent features like addons, +extensions, or bookmarklets. These kinds of features generally advance +the user’s priority over page authors, as espoused in [html-design-principles]. Specifically, extensions SHOULD be able to pass strings +to the injection sinks without triggering default policy execution, violation generation, or the rejection of the value.

+
+
+

Conformance

+

Document conventions

+

Conformance requirements are expressed + with a combination of descriptive assertions + and RFC 2119 terminology. + The key words “MUST”, “MUST NOT”, “REQUIRED”, “SHALL”, “SHALL NOT”, “SHOULD”, “SHOULD NOT”, “RECOMMENDED”, “MAY”, and “OPTIONAL” + in the normative parts of this document + are to be interpreted as described in RFC 2119. + However, for readability, + these words do not appear in all uppercase letters in this specification.

+

All of the text of this specification is normative + except sections explicitly marked as non-normative, examples, and notes. [RFC2119]

+

Examples in this specification are introduced with the words “for example” + or are set apart from the normative text + with class="example", + like this:

+
+ +

This is an example of an informative example.

+
+

Informative notes begin with the word “Note” + and are set apart from the normative text + with class="note", + like this:

+

Note, this is an informative note.

+
+ Tests +

Tests relating to the content of this specification + may be documented in “Tests” blocks like this one. + Any such block is non-normative.

+ +
+
+
+

Conformant Algorithms

+

Requirements phrased in the imperative as part of algorithms + (such as "strip any leading space characters" + or "return false and abort these steps") + are to be interpreted with the meaning of the key word + ("must", "should", "may", etc) + used in introducing the algorithm.

+

Conformance requirements phrased as algorithms or specific steps + can be implemented in any manner, + so long as the end result is equivalent. + In particular, the algorithms defined in this specification + are intended to be easy to understand + and are not intended to be performant. + Implementers are encouraged to optimize.

+
+
+ +

Index

+

Terms defined by this specification

+ +

Terms defined by reference

+ +

References

+

Normative References

+
+
[CSP3] +
Mike West; Antonio Sartori. Content Security Policy Level 3. URL: https://w3c.github.io/webappsec-csp/ +
[DOM] +
Anne van Kesteren. DOM Standard. Living Standard. URL: https://dom.spec.whatwg.org/ +
[ECMASCRIPT] +
ECMAScript Language Specification. URL: https://tc39.es/ecma262/multipage/ +
[Fetch] +
Anne van Kesteren. Fetch Standard. Living Standard. URL: https://fetch.spec.whatwg.org/ +
[FileAPI] +
Marijn Kruisselbrink. File API. URL: https://w3c.github.io/FileAPI/ +
[HTML] +
Anne van Kesteren; et al. HTML Standard. Living Standard. URL: https://html.spec.whatwg.org/multipage/ +
[INFRA] +
Anne van Kesteren; Domenic Denicola. Infra Standard. Living Standard. URL: https://infra.spec.whatwg.org/ +
[RFC2119] +
S. Bradner. Key words for use in RFCs to Indicate Requirement Levels. March 1997. Best Current Practice. URL: https://datatracker.ietf.org/doc/html/rfc2119 +
[SVG2] +
Amelia Bellamy-Royds; et al. Scalable Vector Graphics (SVG) 2. URL: https://svgwg.org/svg2-draft/ +
[URL] +
Anne van Kesteren. URL Standard. Living Standard. URL: https://url.spec.whatwg.org/ +
[WEBIDL] +
Edgar Chen; Timothy Gu. Web IDL Standard. Living Standard. URL: https://webidl.spec.whatwg.org/ +
+

Informative References

+
+
[HTML-DESIGN-PRINCIPLES] +
Anne van Kesteren; Maciej Stachowiak. HTML Design Principles. 26 November 2007. WD. URL: https://www.w3.org/TR/html-design-principles/ +
[HTML5] +
Ian Hickson; et al. HTML5. URL: https://www.w3.org/html/wg/drafts/html/master/ +
+

Issues Index

+
+
The event handler content attribute concept used below is ambiguous. This spec needs a better mechanism to identify event handler attributes. See https://github.com/w3c/trusted-types/issues/520.
+
See https://github.com/whatwg/webidl/pull/1392.
+
Remove hardcoding 'script' when new sink groups are specified.
+
Refer to the external document on secure policy design.
+
+
+ MDN +
+

TrustedHTML/toJSON

+

In only one current engine.

+
+ FirefoxNoneSafariNoneChrome90+ +
+ Opera?Edge90+ +
+ Edge (Legacy)?IENone +
+ Firefox for Android?iOS Safari?Chrome for Android?Android WebView?Samsung Internet?Opera Mobile? +
+
+
+
+ MDN +
+

TrustedHTML/toString

+

In only one current engine.

+
+ FirefoxNoneSafariNoneChrome83+ +
+ Opera?Edge83+ +
+ Edge (Legacy)?IENone +
+ Firefox for Android?iOS Safari?Chrome for Android?Android WebView?Samsung Internet?Opera Mobile? +
+
+
+
+ MDN +
+

TrustedHTML

+

In only one current engine.

+
+ FirefoxNoneSafariNoneChrome83+ +
+ Opera?Edge83+ +
+ Edge (Legacy)?IENone +
+ Firefox for Android?iOS Safari?Chrome for Android?Android WebView?Samsung Internet?Opera Mobile? +
+
+
+
+ MDN +
+

TrustedScript/toJSON

+

In only one current engine.

+
+ FirefoxNoneSafariNoneChrome90+ +
+ Opera?Edge90+ +
+ Edge (Legacy)?IENone +
+ Firefox for Android?iOS Safari?Chrome for Android?Android WebView?Samsung Internet?Opera Mobile? +
+
+
+
+ MDN +
+

TrustedScript/toString

+

In only one current engine.

+
+ FirefoxNoneSafariNoneChrome83+ +
+ Opera?Edge83+ +
+ Edge (Legacy)?IENone +
+ Firefox for Android?iOS Safari?Chrome for Android?Android WebView?Samsung Internet?Opera Mobile? +
+
+
+

TrustedScriptURL/toString

+

In only one current engine.

+
+ FirefoxNoneSafariNoneChrome83+ +
+ Opera?Edge83+ +
+ Edge (Legacy)?IENone +
+ Firefox for Android?iOS Safari?Chrome for Android?Android WebView?Samsung Internet?Opera Mobile? +
+
+
+
+ MDN +
+

TrustedScript

+

In only one current engine.

+
+ FirefoxNoneSafariNoneChrome83+ +
+ Opera?Edge83+ +
+ Edge (Legacy)?IENone +
+ Firefox for Android?iOS Safari?Chrome for Android?Android WebView?Samsung Internet?Opera Mobile? +
+
+
+
+ MDN +
+

TrustedScriptURL/toJSON

+

In only one current engine.

+
+ FirefoxNoneSafariNoneChrome90+ +
+ Opera?Edge90+ +
+ Edge (Legacy)?IENone +
+ Firefox for Android?iOS Safari?Chrome for Android?Android WebView?Samsung Internet?Opera Mobile? +
+
+
+
+ MDN +
+

TrustedScriptURL

+

In only one current engine.

+
+ FirefoxNoneSafariNoneChrome83+ +
+ Opera?Edge83+ +
+ Edge (Legacy)?IENone +
+ Firefox for Android?iOS Safari?Chrome for Android?Android WebView?Samsung Internet?Opera Mobile? +
+
+
+
+ MDN +
+

TrustedTypePolicy/createHTML

+

In only one current engine.

+
+ FirefoxNoneSafariNoneChrome83+ +
+ Opera?Edge83+ +
+ Edge (Legacy)?IENone +
+ Firefox for Android?iOS Safari?Chrome for Android?Android WebView?Samsung Internet?Opera Mobile? +
+
+
+
+ MDN +
+

TrustedTypePolicy/createScript

+

In only one current engine.

+
+ FirefoxNoneSafariNoneChrome83+ +
+ Opera?Edge83+ +
+ Edge (Legacy)?IENone +
+ Firefox for Android?iOS Safari?Chrome for Android?Android WebView?Samsung Internet?Opera Mobile? +
+
+
+
+ MDN +
+

TrustedTypePolicy/createScriptURL

+

In only one current engine.

+
+ FirefoxNoneSafariNoneChrome83+ +
+ Opera?Edge83+ +
+ Edge (Legacy)?IENone +
+ Firefox for Android?iOS Safari?Chrome for Android?Android WebView?Samsung Internet?Opera Mobile? +
+
+
+
+ MDN +
+

TrustedTypePolicy/name

+

In only one current engine.

+
+ FirefoxNoneSafariNoneChrome83+ +
+ Opera?Edge83+ +
+ Edge (Legacy)?IENone +
+ Firefox for Android?iOS Safari?Chrome for Android?Android WebView?Samsung Internet?Opera Mobile? +
+
+
+
+ MDN +
+

TrustedTypePolicy

+

In only one current engine.

+
+ FirefoxNoneSafariNoneChrome83+ +
+ Opera?Edge83+ +
+ Edge (Legacy)?IENone +
+ Firefox for Android?iOS Safari?Chrome for Android?Android WebView?Samsung Internet?Opera Mobile? +
+
+
+
+ MDN +
+

TrustedTypePolicyFactory/createPolicy

+

In only one current engine.

+
+ FirefoxNoneSafariNoneChrome83+ +
+ Opera?Edge83+ +
+ Edge (Legacy)?IENone +
+ Firefox for Android?iOS Safari?Chrome for Android?Android WebView?Samsung Internet?Opera Mobile? +
+
+
+
+ MDN +
+

TrustedTypePolicyFactory/defaultPolicy

+

In only one current engine.

+
+ FirefoxNoneSafariNoneChrome83+ +
+ Opera?Edge83+ +
+ Edge (Legacy)?IENone +
+ Firefox for Android?iOS Safari?Chrome for Android?Android WebView?Samsung Internet?Opera Mobile? +
+
+
+
+ MDN +
+

TrustedTypePolicyFactory/emptyHTML

+

In only one current engine.

+
+ FirefoxNoneSafariNoneChrome83+ +
+ Opera?Edge83+ +
+ Edge (Legacy)?IENone +
+ Firefox for Android?iOS Safari?Chrome for Android?Android WebView?Samsung Internet?Opera Mobile? +
+
+
+
+ MDN +
+

TrustedTypePolicyFactory/emptyScript

+

In only one current engine.

+
+ FirefoxNoneSafariNoneChrome83+ +
+ Opera?Edge83+ +
+ Edge (Legacy)?IENone +
+ Firefox for Android?iOS Safari?Chrome for Android?Android WebView?Samsung Internet?Opera Mobile? +
+
+
+
+ MDN +
+

TrustedTypePolicyFactory/getAttributeType

+

In only one current engine.

+
+ FirefoxNoneSafariNoneChrome83+ +
+ Opera?Edge83+ +
+ Edge (Legacy)?IENone +
+ Firefox for Android?iOS Safari?Chrome for Android?Android WebView?Samsung Internet?Opera Mobile? +
+
+
+
+ MDN +
+

TrustedTypePolicyFactory/getPropertyType

+

In only one current engine.

+
+ FirefoxNoneSafariNoneChrome83+ +
+ Opera?Edge83+ +
+ Edge (Legacy)?IENone +
+ Firefox for Android?iOS Safari?Chrome for Android?Android WebView?Samsung Internet?Opera Mobile? +
+
+
+
+ MDN +
+

TrustedTypePolicyFactory/isHTML

+

In only one current engine.

+
+ FirefoxNoneSafariNoneChrome83+ +
+ Opera?Edge83+ +
+ Edge (Legacy)?IENone +
+ Firefox for Android?iOS Safari?Chrome for Android?Android WebView?Samsung Internet?Opera Mobile? +
+
+
+
+ MDN +
+

TrustedTypePolicyFactory/isScript

+

In only one current engine.

+
+ FirefoxNoneSafariNoneChrome83+ +
+ Opera?Edge83+ +
+ Edge (Legacy)?IENone +
+ Firefox for Android?iOS Safari?Chrome for Android?Android WebView?Samsung Internet?Opera Mobile? +
+
+
+
+ MDN +
+

TrustedTypePolicyFactory/isScriptURL

+

In only one current engine.

+
+ FirefoxNoneSafariNoneChrome83+ +
+ Opera?Edge83+ +
+ Edge (Legacy)?IENone +
+ Firefox for Android?iOS Safari?Chrome for Android?Android WebView?Samsung Internet?Opera Mobile? +
+
+
+
+ MDN +
+

TrustedTypePolicyFactory

+

In only one current engine.

+
+ FirefoxNoneSafariNoneChrome83+ +
+ Opera?Edge83+ +
+ Edge (Legacy)?IENone +
+ Firefox for Android?iOS Safari?Chrome for Android?Android WebView?Samsung Internet?Opera Mobile? +
+
+
+
+ MDN +
+

Headers/Content-Security-Policy/require-trusted-types-for

+

In only one current engine.

+
+ FirefoxNoneSafariNoneChrome83+ +
+ Opera?Edge83+ +
+ Edge (Legacy)?IENone +
+ Firefox for Android?iOS Safari?Chrome for Android?Android WebView?Samsung Internet?Opera Mobile? +
+
+
+
+ MDN +
+

Headers/Content-Security-Policy/trusted-types

+

In only one current engine.

+
+ FirefoxNoneSafariNoneChrome83+ +
+ Opera?Edge83+ +
+ Edge (Legacy)?IENone +
+ Firefox for Android?iOS Safari?Chrome for Android?Android WebView?Samsung Internet?Opera MobileNone +
+
+
+ + + + + + \ No newline at end of file