Tests
- block-Document-execCommand.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)
- Document-write-exception-order.xhtml (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)
- Element-toggleAttribute.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-default-policy-mutate.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)
- modify-attributes-in-callback.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-svg-script-set-href.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-none-name.html (live test) (source)
- TrustedTypePolicyFactory-createPolicy-cspTests-none-none.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)
- SVGScriptElement-internal-slot.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 Type s 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.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), 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 null or 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 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
-
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 null or 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 interface’s name of the value of the fourth 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
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:
-
If policyName is the empty string, throw a TypeError and abort further 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 . -
Set policy ’s options value to «[ "createHTML" -> options ["
createHTML
", "createScript" -> options ["createScript
", "createScriptURL" -> options ["createScriptURL
" ]». -
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 .
-
If policyValue is null or undefined, set dataString to the empty string.
-
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 policy ’s options [ 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. 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:
-
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 fourth member of attributeData .
-
Let sink be the value of the fifth 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.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 .
-
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 (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:
-
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 changed by trusted sink to true.
-
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.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:
-
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 changed by trusted sink to true.
-
Run set text content with this and value .
The
textContent
getter
steps
are:
-
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.
-
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 changed by trusted sink to true.
-
String replace all with the given value within this .
4.1.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.1.2.6. Script children changed steps
This
document
modifies
the
children
changed
steps
for
HTMLScriptElement
as
follows:
-
Set this 's is trusted to false.
-
If this 's changed by trusted sink is true, set this 's is trusted to true.
-
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:
-
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:
-
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. -
Let source text be el ’s child text content .
-
If el ’s is trusted is false:
-
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.
-
- ...
There’s
no
proper
definition
for
the
processing
of
SVG
script
elements.
However,
you
should
apply
a
similar
change
to
the
processing
of
SVGScriptElement
s.
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'"
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.
-
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.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'"
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.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.
-
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.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.
-
Let result be
"Allowed"
. -
Let sample be source .
-
If sink is
"Function"
, then:-
If sample starts with
"function anonymous"
, strip that from sample . -
Otherwise if sample starts with
"async function anonymous"
, strip that from sample . -
Otherwise if sample starts with
"function* anonymous"
, strip that from sample . -
Otherwise if sample starts with
"async function* anonymous"
, strip that from sample .
-
-
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 trimmedSample be the substring of sample , containing its first 40 characters.
-
Set violation ’s sample to be the result of concatenating the list « sink , trimmedSample « using
"|"
as a separator. -
Execute Report a violation on violation .
-
If policy ’s disposition is
"enforce"
, then set result to"Blocked"
.
-
-
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.
-
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 .
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.