Tests
+-
+
- block-Document-execCommand.html (live test) (source) +
- block-Node-multiple-arguments.html (live test) (source) +
- block-string-assignment-to-attribute-via-attribute-node.html (live test) (source) +
- block-string-assignment-to-Document-parseHTMLUnsafe.html (live test) (source) +
- block-string-assignment-to-Document-write.html (live test) (source) +
- block-string-assignment-to-DOMParser-parseFromString.html (live test) (source) +
- block-string-assignment-to-DOMWindowTimers-setTimeout-setInterval.html (live test) (source) +
- block-string-assignment-to-Element-insertAdjacentHTML.html (live test) (source) +
- block-string-assignment-to-Element-outerHTML.html (live test) (source) +
- block-string-assignment-to-Element-setAttribute.html (live test) (source) +
- block-string-assignment-to-Element-setAttributeNS.html (live test) (source) +
- block-string-assignment-to-Element-setHTMLUnsafe.html (live test) (source) +
- block-string-assignment-to-HTMLElement-generic.html (live test) (source) +
- block-string-assignment-to-Range-createContextualFragment.html (live test) (source) +
- block-string-assignment-to-ShadowRoot-setHTMLUnsafe.html (live test) (source) +
- block-text-node-insertion-into-script-element.html (live test) (source) +
- csp-block-eval.html (live test) (source) +
- default-policy-callback-arguments.html (live test) (source) +
- default-policy-report-only.html (live test) (source) +
- default-policy.html (live test) (source) +
- Document-execCommand.html (live test) (source) +
- Document-write.html (live test) (source) +
- DOMParser-parseFromString-regression.html (live test) (source) +
- DOMParser-parseFromString.html (live test) (source) +
- DOMWindowTimers-setTimeout-setInterval.html (live test) (source) +
- Element-insertAdjacentHTML.html (live test) (source) +
- Element-insertAdjacentText.html (live test) (source) +
- Element-outerHTML.html (live test) (source) +
- Element-setAttribute.html (live test) (source) +
- Element-setAttribute-respects-Elements-node-documents-globals-CSP.html (live test) (source) +
- Element-setAttributeNS.html (live test) (source) +
- empty-default-policy-report-only.html (live test) (source) +
- empty-default-policy.html (live test) (source) +
- eval-csp-no-tt.html (live test) (source) +
- eval-csp-tt-default-policy.html (live test) (source) +
- eval-csp-tt-no-default-policy.html (live test) (source) +
- eval-function-constructor.html (live test) (source) +
- eval-no-csp-no-tt-default-policy.html (live test) (source) +
- eval-no-csp-no-tt.html (live test) (source) +
- eval-with-permissive-csp.html (live test) (source) +
- GlobalEventHandlers-onclick.html (live test) (source) +
- HTMLElement-generic.html (live test) (source) +
- HTMLScriptElement-in-xhtml-document.tentative.https.xhtml (live test) (source) +
- HTMLScriptElement-internal-slot.html (live test) (source) +
- idlharness.window.js (live test) (source) +
- no-require-trusted-types-for-report-only.html (live test) (source) +
- no-require-trusted-types-for.html (live test) (source) +
- Node-multiple-arguments.html (live test) (source) +
- Range-createContextualFragment.html (live test) (source) +
- require-trusted-types-for-report-only.html (live test) (source) +
- require-trusted-types-for.html (live test) (source) +
- trusted-types-createHTMLDocument.html (live test) (source) +
- trusted-types-duplicate-names-list-report-only.html (live test) (source) +
- trusted-types-duplicate-names-list.html (live test) (source) +
- trusted-types-duplicate-names-without-enforcement.html (live test) (source) +
- trusted-types-duplicate-names.html (live test) (source) +
- trusted-types-eval-reporting-no-unsafe-eval.html (live test) (source) +
- trusted-types-eval-reporting-report-only.html (live test) (source) +
- trusted-types-eval-reporting.html (live test) (source) +
- trusted-types-event-handlers.html (live test) (source) +
- trusted-types-navigation.html (live test) (source) +
- trusted-types-report-only.html (live test) (source) +
- trusted-types-reporting-check-report.html (live test) (source) +
- trusted-types-reporting.html (live test) (source) +
- trusted-types-source-file-path.html (live test) (source) +
- trusted-types-svg-script.html (live test) (source) +
- trusted-types-tojson.html (live test) (source) +
- TrustedType-AttributeNodes.html (live test) (source) +
- TrustedTypePolicy-createXXX.html (live test) (source) +
- TrustedTypePolicy-CSP-no-name.html (live test) (source) +
- TrustedTypePolicy-CSP-wildcard.html (live test) (source) +
- TrustedTypePolicyFactory-constants.html (live test) (source) +
- TrustedTypePolicyFactory-createPolicy-createXYZTests.html (live test) (source) +
- TrustedTypePolicyFactory-createPolicy-cspTests-noNamesGiven.html (live test) (source) +
- TrustedTypePolicyFactory-createPolicy-cspTests-none-skip.html (live test) (source) +
- TrustedTypePolicyFactory-createPolicy-cspTests-none.html (live test) (source) +
- TrustedTypePolicyFactory-createPolicy-cspTests-wildcard.html (live test) (source) +
- TrustedTypePolicyFactory-createPolicy-cspTests.html (live test) (source) +
- TrustedTypePolicyFactory-createPolicy-nameTests.html (live test) (source) +
- TrustedTypePolicyFactory-createPolicy-unenforced.html (live test) (source) +
- TrustedTypePolicyFactory-defaultPolicy.html (live test) (source) +
- TrustedTypePolicyFactory-getAttributeType-namespace.html (live test) (source) +
- TrustedTypePolicyFactory-getAttributeType-svg.html (live test) (source) +
- TrustedTypePolicyFactory-isXXX.html (live test) (source) +
- tt-block-eval.html (live test) (source) +
- Window-TrustedTypes.html (live test) (source) +
- worker-constructor.https.html (live test) (source) +
- WorkerGlobalScope-eval.html (live test) (source) +
- WorkerGlobalScope-importScripts.html (live test) (source) +
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
+-
+
-
+
Minimize the likelihood of client-side vulnerabilities that occur when +calling powerful Web APIs with untrusted data - for example, +minimize the likelihood of DOM XSS.
+ -
+
Encourage a design in which security decisions are +encapsulated within a small part of the application.
+ -
+
Reduce security review surface for complex web application +codebases.
+ -
+
Allow the usability-preserving detection of vulnerabilities similar to how regular +programming errors are detected and surfaced to the developers, with the +assist of dynamic and static analysis tools.
+
1.2. Non-goals
+-
+
-
+
Prevent, or mitigate the result of injections into server-side generated +markup, in specific reflections into the body of the scripts running in a +document. To address server-side XSS vectors, we recommend existing +solutions like templating systems or CSP script-src.
+ -
+
Address resource confinement, e.g. to prevent data exfiltration, or +connecting to external sources via [Fetch].
+ -
+
Control subresource loading. Trusted Types aim to allow the authors to +control loading resources that can script the current document, but not +other subresources.
+ -
+
Prevent cross-origin JavaScript execution (for example, Trusted Types +don’t guard loading new documents with JavaScript code via
+data:
URLs). -
+
Prevent malicious authors of the web application’s JavaScript code +from being able to bypass the restrictions; attempting to protect against +malicious authors would result in an overly complex and not-practical +design.
+
1.3. Use cases
+-
+
-
+
An author maintains a complex web application written in a framework +that uses a secure templating system to generate the UI +components. The application also depends on 3rd party client-side +libraries that perform auxiliary tasks (e.g. analytics, performance +monitoring). To ensure that none of these components introduce DOM +XSS vulnerabilities, author defines a Trusted Type policy in the +templating library and enables the enforcement for the § 2.1.1 DOM XSS injection sinks.
+ -
+
A website uses § 2.1.1 DOM XSS injection sinks. The website-developer adds trusted +types to it and monitors violations by using the Content-Security-Policy-Report-Only header field. +Violations are iteratively fixed by refactoring the code to use only safe +methods. Afterwards, no § 2.1.1 DOM XSS injection sinks are called anymore. +Hence, no trusted types are required anymore. The developer switches the +report-only mode off and disables trusted type policies with the trusted-types and the require-trusted-types-for directives. +The website’s functionality was never impaired during the refactorings.
+ -
+
A large team maintains a complex client-side application. +They create a number of Trusted Types policies that satisfy the security +requirements for the application. The team consolidates the policy +implementations and the safe abstractions that use them in a small number +of heavily reviewed files and requires extra approval for commits that +affect these files.
+The need to create trusted values to affect injection sinks, +combined with additional scrutiny on changes that affect policy +code, incents developers to use safe abstractions instead of writing ad-hoc +string composition code when interacting with § 2.1.1 DOM XSS injection sinks.
+When considering the risk of DOM XSS, security auditors find a +small attack surface; they focus on the small amount of code that +crafts the CSP header and provides the safe abstractions, and ignore the +bulk of client-side application code.
+ -
+
An existing web application interacts with the DOM mostly using XSS-safe +patterns (i.e. without using § 2.1.1 DOM XSS injection sinks). In a few places, +however, it resorts to using risky patterns like loading additional script using +JSONP, calling into
+innerHTML
oreval
.Review finds that those places do not cause XSS (e.g. because +user-controlled data is not part of the input to those sinks), but it’s +hard to migrate the application off using these patterns.
+As such, CSP cannot be enforced on this application (without resorting to +an unsafe version using
+'unsafe-eval' 'unsafe-inline'
). Additionally, +it’s possible some codebase with DOM XSS flaws was not included in a review, +or will be introduced in the future.To address this risk, the author converts the reviewed parts to using +Trusted Types, and enables Trusted Type enforcement. Additional places +using the injection sinks, should they exist in the future, are correctly +blocked and reported.
+ -
+
A security team is tasked with assuring that the client-side heavy +application code does not contain XSS vulnerabilities. Since the server side +code is homogeneous (it’s mostly an API backend), and the application +enforces Trusted Types, the review only focuses on the Trusted Type policies and their rules. Later on the reviewed policy names are +allowed in the 'trusted-types' CSP directive, safe for the developers to +use.
+Any additional code, including the code of often-changing dependencies, +can be excluded from the review, unless it creates a Trusted Type policy. +Without it, the code cannot cause a DOM XSS.
+
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:
+-
+
-
+
Setters for
+Element
attributes that accept a URL of the code to load +likeHTMLScriptElement.src
, -
+
Setters for
+Element
attributes that accept a code to execute likeHTMLScriptElement.text
, -
+
Functions that execute code directly like
+eval
, -
+
Navigation to 'javascript:' URLs.
+
Since HTML parsers can create arbitrary elements, including scripts, and set arbitrary attributes, +DOM XSS injection sinks also include HTML parsing sinks:
+-
+
-
+
Functions that parse & insert HTML strings into the document like
+Element.innerHTML
,ShadowRoot.innerHTML
, +andElement.outerHTML
setters, or Document.write. -
+
Functions that create a new same-origin
+Document
with caller-controlled +markup likeparseFromString()
.
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.
+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.
++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).
+( 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), +andcreatePolicy
is called more than once with any givenpolicyName
, +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. 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:
+-
+
-
+
Set localName to tagName in ASCII lowercase.
+ -
+
If elementNs is an empty string, set elementNs to HTML namespace.
+ -
+
Let interface be the element interface for localName and elementNs.
+ -
+
Let expectedType be null.
+ -
+
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
+ -
+
Return expectedType.
+
-
+
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 +toElement.setAttribute
passes the correct argument type.This function returns the result of the following algorithm:
+-
+
-
+
Set localName to tagName in ASCII lowercase.
+ -
+
Set attribute to attribute in ASCII lowercase.
+ -
+
If elementNs is an empty string, set elementNs to HTML namespace.
+ -
+
If attrNs is an empty string, set attrNs to null.
+ -
+
Let interface be the element interface for localName and elementNs.
+ -
+
Let expectedType be null.
+ -
+
Set attributeData to the result of Get Trusted Type data for attribute algorithm, with the following arguments:
+-
+
-
+
interface as element
+ -
+
attribute
+ -
+
attrNs
+
-
+
-
+
If attributeData is not null, then set expectedType to the value of the third member of attributeData.
+ -
+
Return expectedType.
+
-
+
-
+
emptyHTML
, of type TrustedHTML, readonly +-
+
is a
+TrustedHTML
object with its data value set to an empty string.
-
+
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.
+
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:
-
+
-
+
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.
+ -
+
If allowedByCSP is
+"Blocked"
, throw a TypeError and abort further steps. -
+
If policyName is
+default
and the factory’s default policy value is not null, throw a TypeError and abort further steps. -
+
Let policy be a new
+TrustedTypePolicy
object. -
+
Set policy’s
+name
property value to policyName. -
+
Let policyOptions be a new
+TrustedTypePolicyOptions
object. -
+
Set policyOptions
+createHTML
property to options’createHTML
property value. -
+
Set policyOptions
+createScript
property to options’createScript
property value. -
+
Set policyOptions
+createScriptURL
property to options’createScriptURL
property value. -
+
Set policy’s options value to policyOptions.
+ -
+
If the policyName is
+default
, set the factory’s default policy value to policy. -
+
Append policyName to factory’s created policy names.
+ -
+
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:
-
+
-
+
Let policyValue be the result of executing Get Trusted Type policy value with the same arguments as this algorithm and additionally true as throwIfMissing.
+ -
+
If the algorithm threw an error, rethrow the error and abort the following steps.
+ -
+
Let dataString be the result of stringifying policyValue.
+ -
+
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:
-
+
-
+
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" + -
+
Let function be the value of the property in policy’s options named functionName.
+ -
+
If function is
+null
, then:-
+
-
+
If throwIfMissing throw a TypeError.
+ -
+
Else return
+null
.
-
+
-
+
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. -
+
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:
-
+
-
+
If input has type expectedType, return stringified input and abort these steps.
+ -
+
Let requireTrustedTypes be the result of executing Does sink type require trusted types? algorithm, +passing global, and sinkGroup.
+ -
+
If requireTrustedTypes is
+false
, return stringified input and abort these steps. -
+
Let convertedInput be the result of executing Process value with a default policy with the same arguments as this algorithm.
+ -
+
If the algorithm threw an error, rethrow the error and abort the following steps.
+ -
+
If convertedInput is
+null
orundefined
, execute the following steps:-
+
-
+
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.
+ -
+
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.
+ -
+
Throw a TypeError and abort further steps.
+
-
+
-
+
Assert: convertedInput has type expectedType.
+ -
+
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:
-
+
-
+
Let defaultPolicy be the value of global’s trusted type policy factory's default policy.
+ -
+
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
+
-
+
-
+
If the algorithm threw an error, rethrow the error and abort the following steps.
+ -
+
If policyValue is null or undefined, return policyValue.
+ -
+
Let dataString be the result of stringifying policyValue.
+ -
+
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:
-
+
-
+
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:
+-
+
-
+
+TrustedScriptURL
as expectedType, -
+
script’s
+Document
's relevant global object as global, -
+
script’s child text content attribute value,
+ -
+
+HTMLScriptElement text
as sink, -
+
+'script'
as sinkGroup.
If the algorithm threw an error, rethrow the error.
+ -
+
3.7. Get Trusted Types-compliant attribute value
+ To get Trusted Types-compliant attribute value onAttr
attribute with Element
element and TrustedType
or a string newValue, perform the following steps:
+ -
+
-
+
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
+
-
+
-
+
If attributeData is null, then:
+-
+
-
+
If newValue is a string, return newValue.
+ -
+
Assert: newValue is
+TrustedHTML
orTrustedScript
orTrustedScriptURL
. -
+
Return value’s associated data.
+
-
+
-
+
Let expectedType be the value of the third member of attributeData.
+ -
+
Let sink be the value of the fourth member of attributeData.
+ -
+
Return the result of executing Get Trusted Type compliant string with the following arguments:
+-
+
-
+
expectedType
+ -
+
newValue as input
+ -
+
element’s node document’s relevant global object as global
+ -
+
sink
+ -
+
'script' as sinkGroup
+
-
+
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.
+-
+
-
+
Let data be null.
+ -
+
If attributeNs is null, and attribute is the name of an event handler content attribute, then:
+-
+
-
+
Return (
+Element
, null, attribute,TrustedScript
, "Element " + attribute).
-
+
-
+
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" + -
+
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 HTMLScriptElement
s. 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:
-
+
-
+
Let value be the result of calling Get Trusted Type compliant string with
+TrustedScript
, this's relevant global object, the given value,HTMLScriptElement innerText
, andscript
. -
+
Set this's script text value to value.
+ -
+
Run set the inner text steps with this and value.
+
The innerText
getter steps are:
-
+
-
+
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:
-
+
-
+
Let value be the result of calling Get Trusted Type compliant string with
+TrustedScript
, this's relevant global object, the given value,HTMLScriptElement textContent
, andscript
. -
+
Set this's script text value to value.
+ -
+
Run set text content with this and value.
+
The textContent
getter steps are:
-
+
-
+
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.
-
+
-
+ Let value be the result of calling Get Trusted Type compliant string with
TrustedScript
, this's relevant global object, the given value,HTMLScriptElement text
, andscript
. + - + Set this's script text value to the given value. +
-
+
String replace all with the given value within this.
+
4.3.2.5. The src
IDL attribute
+ The src
setter steps are:
-
+
-
+ Let value be the result of calling Get Trusted Type compliant string with
TrustedScriptURL
, this's relevant global object, the given value,HTMLScriptElement src
, andscript
. + - + 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:
+-
+
-
+
If el’s already started is true, then return.
+ -
+
Let parser document be el’s parser document.
+ -
+
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. -
+
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 theasync
attribute isn’t set. -
+
+
Execute the Prepare the script text algorithm on el. If that algorithm threw an error, then return.
+ + -
+
+ Let source text be el’s +
+child text content.+ script text value. + - ... +
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: +
+-
+
-
+
+ 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:
+-
+
-
+
If argument is a
+TrustedScript
object, return the value of its associated data. -
+
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:
+-
+
-
+
If platformObject’s relevant global object has a trusted type policy factory:
+-
+
-
+
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"
. -
+
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.
+ -
+
-
+
If an exception was thrown, rethrow exception and abort further steps.
+
-
+
-
+
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'" ++
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.
-
+
-
+
If request’s url's scheme is not
+"javascript"
, return"Allowed"
and abort further steps. -
+
Let urlString be the result of running the URL serializer on request’s url.
+ -
+
Let encodedScriptSource be the result of removing the leading
+"javascript:"
from urlString. -
+
Let convertedScriptSource be the result of executing Process value with a default policy algorithm, with the following arguments:
+-
+
-
+
+TrustedScript
as expectedType -
+
request’s clients's global object as global
+ -
+
encodedScriptSource as input
+ -
+
+"Location href"
as sink
If that algorithm threw an error or convertedScriptSource is not a
+TrustedScript
object, return "Blocked" and abort further steps. -
+
-
+
Set urlString to be the result of prepending
+"javascript:"
to stringified convertedScriptSource. -
+
Let newURL be the result of running the URL parser on urlString. If the parser returns a failure, return
+"Blocked"
and abort further steps. -
+
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. -
+
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'" ++
Content-Security-Policy: require-trusted-types-for 'script'; trusted-types one two ++
Content-Security-Policy: trusted-types; require-trusted-types-for 'script' ++
The keyword 'none'
may be used to explicitly express the above:
Keyword 'allow-duplicates'
allows for creating policies with a name that was already used.
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.
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.
-
+
-
+
Let result be
+false
. -
+
For each policy in global’s CSP list:
+-
+
-
+
If policy’s directive set does not contain a directive whose name is
+"require-trusted-types-for"
, skip to the next policy. -
+
Let directive be the policy’s directive set’s directive whose name +is
+"require-trusted-types-for"
-
+
If directive’s value does not contain a trusted-types-sink-group which is a match +for sinkGroup, skip to the next policy.
+ -
+
Set result to
+true
.
-
+
-
+
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.
-
+
-
+
Let result be
+"Allowed"
. -
+
For each policy in global’s CSP list:
+-
+
-
+
If policy’s directive set does not contain a directive whose name is
+"require-trusted-types-for"
, skip to the next policy. -
+
Let directive be the policy’s directive set’s directive whose name +is
+"require-trusted-types-for"
-
+
If directive’s value does not contain a trusted-types-sink-group which is a match +for sinkGroup, skip to the next policy.
+ -
+
Let violation be the result of executing Create a violation object for global, policy, and directive on global, policy and
+"require-trusted-types-for"
-
+
Set violation’s resource to
+"trusted-types-sink"
. -
+
Let trimmedSource be the substring of source, containing its first 40 characters.
+ -
+
Set violation’s sample to be the result of concatenating the list « sink, trimmedSource « using
+"|"
as a separator. -
+
Execute Report a violation on violation.
+ -
+
If policy’s disposition is
+"enforce"
, then set result to"Blocked"
.
-
+
-
+
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.
-
+
-
+
Let result be
+"Allowed"
. -
+
For each policy in global’s CSP list:
+-
+
-
+
Let createViolation be false.
+ -
+
If policy’s directive set does not contain a directive which name is
+"trusted-types"
, skip to the next policy. -
+
Let directive be the policy’s directive set’s directive which name +is
+"trusted-types"
-
+
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.
+ -
+
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. -
+
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, usetrusted-types * 'allow-duplicates'
or don’t set thetrusted-types
directive at all. -
+
If createViolation is false, skip to the next policy.
+ -
+
Let violation be the result of executing Create a violation object for global, policy, and directive on global, policy and
+"trusted-types"
-
+
Set violation’s resource to
+"trusted-types-policy"
. -
+
Set violation’s sample to the substring of policyName, containing its first 40 characters.
+ -
+
Execute Report a violation on violation.
+ -
+
If policy’s disposition is
+"enforce"
, then set result to"Blocked"
.
-
+
-
+
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.
+