[go: up one dir, main page]

Trusted Types

W3C Working Draft,

More details about this document
This version:
https://www.w3.org/TR/2024/WD-trusted-types-20241028/
Latest published version:
https://www.w3.org/TR/trusted-types/
Editor's Draft:
https://w3c.github.io/trusted-types/dist/spec/
Previous Versions:
History:
https://www.w3.org/standards/history/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 section describes the status of this document at the time of its publication. A list of current W3C publications and the latest revision of this technical report can be found in the W3C technical reports index at https://www.w3.org/TR/.

This document was published by the Web Application Security Working Group as a Working Draft using the Recommendation track. This document is intended to become a W3C Recommendation.

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…

Publication as a Working Draft does not imply endorsement by W3C and its Members. This is a draft document and may be updated, replaced or obsoleted by other documents at any time. It is inappropriate to cite this document as other than work in progress.

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.1.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 null or 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 interface’s name of 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 null or 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 interface’s name of the value of the fourth 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 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. Set policy’s options value to «[ "createHTML" -> options["createHTML", "createScript" -> options["createScript", "createScriptURL" -> options["createScriptURL" ]».

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

  8. Append policyName to factory’s created policy names.

  9. 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. If policyValue is null or undefined, set dataString to the empty string.

  5. 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 policy’s options[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. 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:

  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 fourth member of attributeData.

  4. Let sink be the value of the fifth 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.7. 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 (TrustedHTML or TrustedScript or TrustedScriptURL) TrustedType;

4.1. Integration with HTML

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

4.1.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.1.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.1.2.1. Slots with trusted values

An HTMLScriptElement and SVGScriptElement have:

an associated boolean is trusted.

A boolean indicating whether a script element is considered trustworthy for execution. Initially true.

Note: This boolean is initially true so that parsed scripts are trusted.

an associated boolean changed by trusted sink.

A boolean indicating whether a script element has been modified by a trusted sink. Initially false.

4.1.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 changed by trusted sink to true.

  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.1.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 changed by trusted sink to true.

  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.1.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 changed by trusted sink to true.

  3. String replace all with the given value within this.

4.1.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.1.2.6. Script children changed steps

This document modifies the children changed steps for HTMLScriptElement as follows:

  1. Set this's is trusted to false.

  2. If this's changed by trusted sink is true, set this's is trusted to true.

  3. Set this's changed by trusted sink to false.

Note: This relies on the children changed steps never being called by the parser.

Need to double check how part of script element’s spec fits into this. These steps need to happen before prepare the script is called.

This document modifies the children changed steps for SVGScriptElement as follows:

  1. Set this's is trusted to false.

Note: This relies on the children changed steps never being called by the parser.

4.1.2.7. 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. Let source text be el’s child text content.

  6. If el’s is trusted is false:

    1. Set source text to the result of executing Get Trusted Type compliant string, with TrustedScript, el’s relevant global object, source text, 'HTMLScriptElement text', and 'script'.

      If that algorithm threw an error, then return.

  7. ...

There’s no proper definition for the processing of SVG script elements. However, you should apply a similar change to the processing of SVGScriptElements.

4.2. 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.3. Integration with Content Security Policy

4.3.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.3.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.3.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.3.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.3.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. Let sample be source.

  3. If sink is "Function", then:

    1. If sample starts with "function anonymous", strip that from sample.

    2. Otherwise if sample starts with "async function anonymous", strip that from sample.

    3. Otherwise if sample starts with "function* anonymous", strip that from sample.

    4. Otherwise if sample starts with "async function* anonymous", strip that from sample.

  4. 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 trimmedSample be the substring of sample, containing its first 40 characters.

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

    8. Execute Report a violation on violation.

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

  5. Return result.

4.3.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.

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. 14 October 2024. WD. URL: https://www.w3.org/TR/CSP3/
[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. 24 October 2024. WD. URL: https://www.w3.org/TR/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. 4 October 2018. CR. URL: https://www.w3.org/TR/SVG2/
[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. 27 March 2018. REC. URL: https://www.w3.org/TR/html5/

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.
Need to double check how part of script element’s spec fits into this. These steps need to happen before prepare the script is called.
There’s no proper definition for the processing of SVG script elements. However, you should apply a similar change to the processing of SVGScriptElements.
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