1. Introduction
This section is not normative.
This document defines Content Security Policy (CSP), a tool which developers can use to lock down their applications in various ways, mitigating the risk of content injection vulnerabilities such as cross-site scripting, and reducing the privilege with which their applications execute.
CSP is not intended as a first line of defense against content injection vulnerabilities. Instead, CSP is best used as defense-in-depth. It reduces the harm that a malicious injection can cause, but it is not a replacement for careful input validation and output encoding.
This document is an iteration on Content Security Policy Level 2, with the goal of more clearly explaining the interactions between CSP, HTML, and Fetch on the one hand, and providing clear hooks for modular extensibility on the other. Ideally, this will form a stable core upon which we can build new functionality.
1.1. Examples
1.1.1. Control Execution
Content-Security-Policy: script-src https://cdn.example.com/scripts/; object-src 'none'
1.2. Goals
Content Security Policy aims to do to a few related things:
-
Mitigate the risk of content-injection attacks by giving developers fairly granular control over
-
Mitigate the risk of attacks which require a resource to be embedded in a malicious context (the "Pixel Perfect" attack described in [TIMING], for example) by giving developers granular control over the origins which can embed a given resource.
-
Provide a policy framework which allows developers to reduce the privilege of their applications.
-
Provide a reporting mechanism which allows developers to detect flaws being exploited in the wild.
1.3. Changes from Level 2
This document describes an evolution of the Content Security Policy Level 2 specification [CSP2]. The following is a high-level overview of the changes:
-
The specification has been rewritten from the ground up in terms of the [FETCH] specification, which should make it simpler to integrate CSP’s requirements and restrictions with other specifications (and with Service Workers in particular).
-
The
child-src
model has been substantially altered:-
The
frame-src
directive, which was deprecated in CSP Level 2, has been undeprecated, but continues to defer tochild-src
if not present (which defers todefault-src
in turn). -
A
worker-src
directive has been added, deferring tochild-src
if not present (which likewise defers toscript-src
and eventuallydefault-src
).
-
-
The URL matching algorithm now treats insecure schemes and ports as matching their secure variants. That is, the source expression
http://example.com:80
will match bothhttp://example.com:80
andhttps://example.com:443
.Likewise,
'self'
now matcheshttps:
andwss:
variants of the page’s origin, even on pages whose scheme ishttp
. -
Violation reports generated from inline script or style will now report "
inline
" as the blocked resource. Likewise, blockedeval()
execution will report "eval
" as the blocked resource. -
The
manifest-src
directive has been added. -
The
report-uri
directive is deprecated in favor of the newreport-to
directive, which relies on [REPORTING] as infrastructure. -
The
'strict-dynamic'
source expression will now allow script which executes on a page to load more script via non-"parser-inserted"script
elements. Details are in § 8.2 Usage of "'strict-dynamic'". -
The
'unsafe-hashes'
source expression will now allow event handlers, style attributes andjavascript:
navigation targets to match hashes. Details in § 8.3 Usage of "'unsafe-hashes'". -
The source expression matching has been changed to require explicit presence of any non-HTTP(S) scheme, rather than local scheme, unless that non-HTTP(S) scheme is the same as the scheme of protected resource, as described in § 6.7.2.8 Does url match expression in origin with redirect count?.
-
Hash-based source expressions may now match external scripts if the
script
element that triggers the request specifies a set of integrity metadata which is listed in the current policy. Details in § 8.4 Allowing external JavaScript via hashes. -
Reports generated for inline violations will contain a sample attribute if the relevant directive contains the
'report-sample'
expression.
2. Framework
2.1. Infrastructure
This document uses ABNF grammar to specify syntax, as defined in [RFC5234]. It also relies on
the #rule
ABNF extension defined in
Section 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
".
Each policy has an associated self-origin, which
is an origin that is used when matching the 'self'
keyword.
Note: This is needed to facilitate the 'self'
checks of
local scheme documents/workers that have inherited their policy but
have an opaque origin. Most of the time this will simply be the
environment settings object’s origin.
Multiple policies can be applied to a single resource, and are collected into a list of policies known as a CSP list.
A CSP list contains a header-delivered Content Security Policy if it
contains a policy whose source is "header
".
A serialized CSP is an ASCII string consisting of a semicolon-delimited series of serialized directives, adhering to the following ABNF grammar [RFC5234]:
serialized-policy = serialized-directive *( optional-ascii-whitespace ";" [ optional-ascii-whitespace serialized-directive ] )
A serialized CSP list is an ASCII string consisting of a comma-delimited series of serialized CSPs, adhering to the following ABNF grammar [RFC5234]:
serialized-policy-list = 1#serialized-policy ; The '#' rule is the one defined in section 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 list of Content Security Policy objects. If the policies cannot be parsed, the returned list will be empty.
-
Let policies be an empty list.
-
For each token returned by extracting header list values given
Content-Security-Policy
and response’s header list:-
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 extracting header list values given
Content-Security-Policy-Report-Only
and response’s header list:-
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.
-
-
For each policy of policies:
-
Set policy’s self-origin to response’s url’s origin.
-
-
Return policies.
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 contains a header-delivered Content Security Policy 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 and a policy 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, and a policy 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
Document
or 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
"), and a policy 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
"), and a policy 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'"
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
Window
object, 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.
3. Policy Delivery
A server MAY declare a policy for a particular resource representation via an HTTP response header field whose value is a serialized CSP. This mechanism is defined in detail in § 3.1 The Content-Security-Policy HTTP Response Header Field and § 3.2 The Content-Security-Policy-Report-Only HTTP Response Header Field, and the integration with Fetch and HTML is described in § 4.1 Integration with Fetch and § 4.2 Integration with HTML.
A policy may also be declared inline in an HTML document via a
meta
element’s http-equiv
attribute, as described in
§ 3.3 The <meta> element.
3.1.
The Content-Security-Policy
HTTP Response Header Field
The Content-Security-Policy
HTTP response header field is the preferred mechanism for delivering a policy from a server to a
client. The header’s value is represented by the following ABNF [RFC5234]:
Content-Security-Policy = 1#serialized-policy ; The '#' rule is the one defined in section 5.6.1 of RFC 9110 ; but it incorporates the modifications specified ; in section 2.1 of this document.
Content-Security-Policy: script-src 'self'; report-to csp-reporting-endpoint
A server MAY send different Content-Security-Policy
header field
values with different representations of the same resource.
When the user agent receives a Content-Security-Policy
header field, it
MUST parse and enforce each
serialized CSP it contains as described in § 4.1 Integration with Fetch,
§ 4.2 Integration with HTML.
3.2.
The Content-Security-Policy-Report-Only
HTTP Response Header Field
The Content-Security-Policy-Report-Only
HTTP response header field allows web developers to experiment with policies by monitoring (but
not enforcing) their effects. The header’s value is represented by the following ABNF
[RFC5234]:
Content-Security-Policy-Report-Only = 1#serialized-policy ; The '#' rule is the one defined in section 5.6.1 of RFC 9110 ; but it incorporates the modifications specified ; in section 2.1 of this document.
This header field allows developers to piece together their security policy in an iterative fashion, deploying a report-only policy based on their best estimate of how their site behaves, watching for violation reports, and then moving to an enforced policy once they’ve gained confidence in that behavior.
Content-Security-Policy-Report-Only: script-src 'self'; report-to csp-reporting-endpoint
A server MAY send different Content-Security-Policy-Report-Only
header field values with different representations of the same
resource.
When the user agent receives a Content-Security-Policy-Report-Only
header
field, it MUST parse and monitor
each serialized CSP it contains as described in
§ 4.1 Integration with Fetch and § 4.2 Integration with HTML.
Note: The Content-Security-Policy-Report-Only
header is
not supported inside a meta
element.
3.3.
The <meta>
element
A Document
may deliver a policy via one or more HTML meta
elements
whose http-equiv
attributes are an ASCII case-insensitive
match for the string "Content-Security-Policy
". For example:
Implementation details can be found in HTML’s Content Security Policy
state http-equiv
processing instructions [HTML].
Note: The Content-Security-Policy-Report-Only
header is not
supported inside a meta
element. Neither are the report-uri
,
frame-ancestors
, and sandbox
directives.
Authors are strongly encouraged to place meta
elements as early
in the document as possible, because policies in meta
elements are not
applied to content which precedes them. In particular, note that resources
fetched or prefetched using the Link
HTTP response header
field, and resources fetched or prefetched using link
and script
elements which precede a meta
-delivered policy will not be blocked.
Note: A policy specified via a meta
element will be enforced along with
any other policies active for the protected resource, regardless
of where they’re specified. The general impact of enforcing multiple
policies is described in § 8.1 The effect of multiple policies.
Note: Modifications to the content
attribute of a meta
element
after the element has been parsed will be ignored.
4. Integrations
This section is non-normative.
This document defines a set of algorithms which are used in other specifications in order to implement the functionality. These integrations are outlined here for clarity, but those external documents are the normative references which ought to be consulted for detailed information.
4.1. Integration with Fetch
A number of directives control resource loading in one way or another. This specification provides algorithms which allow Fetch to make decisions about whether or not a particular request should be blocked or allowed, and about whether a particular response should be replaced with a network error.
-
§ 4.1.2 Should request be blocked by Content Security Policy? is called as part of step 2.4 of the Main Fetch algorithm. This allows directives' pre-request checks to be executed against each request before it hits the network, and against each redirect that a request might go through on its way to reaching a resource.
-
§ 4.1.3 Should response to request be blocked by Content Security Policy? is called as part of step 11 of the Main Fetch algorithm. This allows directives' post-request checks to be executed on the response delivered from the network or from a Service Worker.
4.1.1. Report Content Security Policy violations for request
Given a request request, this algorithm reports violations based on policy container’s CSP list "report only" policies.
-
Let CSP list be request’s policy container’s CSP list.
-
For each policy of CSP list:
-
If policy’s disposition is "
enforce
", then skip to the next policy. -
Let violates be the result of executing § 6.7.2.1 Does request violate policy? on request and policy.
-
If violates is not "
Does Not Violate
", then execute § 5.5 Report a violation on the result of executing § 2.4.2 Create a violation object for request, and policy. on request, and policy.
-
4.1.2. Should request be blocked by Content Security Policy?
Given a request request, this algorithm returns Blocked
or Allowed
and
reports violations based on request’s policy container’s
CSP list.
-
Let CSP list be request’s policy container’s CSP list.
-
Let result be "
Allowed
". -
For each policy of CSP list:
-
If policy’s disposition is "
report
", then skip to the next policy. -
Let violates be the result of executing § 6.7.2.1 Does request violate policy? on request and policy.
-
If violates is not "
Does Not Violate
", then:-
Execute § 5.5 Report a violation on the result of executing § 2.4.2 Create a violation object for request, and policy. on request, and policy.
-
Set result to "
Blocked
".
-
-
-
Return result.
4.1.3. Should response to request be blocked by Content Security Policy?
Given a response response and a request request, this algorithm
returns Blocked
or Allowed
, and reports violations based on request’s
policy container’s CSP list.
-
Let CSP list be request’s policy container’s CSP list.
-
Let result be "
Allowed
". -
For each policy of CSP list:
-
For each directive of policy:
-
If the result of executing directive’s post-request check is "
Blocked
", then:-
Execute § 5.5 Report a violation on the result of executing § 2.4.2 Create a violation object for request, and policy. on request, and policy.
-
If policy’s disposition is "
enforce
", then set result to "Blocked
".
-
-
Note: This portion of the check verifies that the page can load the response. That is, that a Service Worker hasn’t substituted a file which would violate the page’s CSP.
-
-
Return result.
4.1.4. Potentially report hash
Given a response response, a request request, a directive directive and a content security policy object policy, run the following steps:
-
Let algorithm be the empty string.
-
If directive’s value contains the expression "
'report-sha256'
", set algorithm to "sha256". -
If directive’s value contains the expression "
'report-sha384'
", set algorithm to "sha384". -
If directive’s value contains the expression "
'report-sha512'
", set algorithm to "sha512". -
If algorithm is the empty string, return.
-
Let hash be the empty string.
-
If response is CORS-same-origin, then:
-
Let h be the result of applying algorithm to bytes on response’s body and algorithm.
-
Let hash be the concatenation of algorithm, U+2D (-), and h.
-
-
Let global be the request’s client’s global object.
-
If global is not a
Window
, return. -
Let stripped document URL to be the result of executing § 5.4 Strip URL for use in reports on global’s document’s URL.
-
If policy’s directive set does not contain a directive named "report-to", return.
-
Let report-to directive be a directive named "report-to" from policy’s directive set.
-
Let body be a csp hash report body with stripped document URL as its documentURL, request’s URL as its subresourceURL, hash as its hash, request’s destination as its destination, and "subresource" as its type.
-
Generate and queue a report with the following arguments:
- context
-
settings object
- type
-
"csp-hash"
- destination
-
report-to directive’s value.
- data
-
body
4.2. Integration with HTML
-
The policy container has a CSP list, which holds all the policy objects which are active for a given context. This list is empty unless otherwise specified, and is populated from the response by parsing response’s Content Security Policies or inherited following the rules of the policy container.
-
A global object’s CSP list is the result of executing § 4.2.2 Retrieve the CSP list of an object with the global object as the
object
. -
A policy is enforced or monitored for a global object by inserting it into the global object’s CSP list.
-
§ 4.2.1 Run CSP initialization for a Document is called during the create and initialize a new
Document
object algorithm. -
§ 4.2.3 Should element’s inline type behavior be blocked by Content Security Policy? is called during the prepare the script element and update a
style
block algorithms in order to determine whether or not an inline script or style block is allowed to execute/render. -
§ 4.2.3 Should element’s inline type behavior be blocked by Content Security Policy? is called during handling of inline event handlers (like
onclick
) and inlinestyle
attributes in order to determine whether or not they ought to be allowed to execute/render. -
policy is enforced during processing of the
meta
element’shttp-equiv
. -
HTML populates each request’s cryptographic nonce metadata and parser metadata with relevant data from the elements responsible for resource loading.
Stylesheet loading is not yet integrated with Fetch in WHATWG’s HTML. [whatwg/html Issue #968]
-
§ 6.3.1.1 Is base allowed for document? is called during
base
’s set the frozen base URL algorithm to ensure that thehref
attribute’s value is valid. -
§ 4.2.4 Should navigation request of type be blocked by Content Security Policy? is called during the create navigation params by fetching algorithm, and § 4.2.5 Should navigation response to navigation request of type in target be blocked by Content Security Policy? is called during the attempt to populate the history entry’s document algorithm to apply directive’s navigation checks, as well as inline checks for navigations to
javascript:
URLs. -
§ 4.2.6 Run CSP initialization for a global object is called during the run a worker algorithm.
-
The sandbox directive is used to populate the CSP-derived sandboxing flags.
4.2.1.
Run CSP
initialization for a Document
Given a Document
document, the user agent performs the following
steps in order to initialize CSP for document:
-
For each policy of document’s policy container’s CSP list:
-
For each directive of policy:
-
Execute directive’s initialization algorithm on document, and assert: its returned value is "
Allowed
".
-
-
4.2.2. Retrieve the CSP list of an object
To obtain object’s CSP list:
-
If object is a
Document
return object’s policy container’s CSP list. -
If object is a
Window
or aWorkerGlobalScope
or aWorkletGlobalScope
, return environment settings object’s policy container’s CSP list. -
Return null.
4.2.3. Should element’s inline type behavior be blocked by Content Security Policy?
Given an Element
element, a string type, and a string source
this algorithm returns "Allowed
" if the element is allowed to have inline
definition of a particular type of behavior (script execution, style
application, event handlers, etc.), and "Blocked
" otherwise:
Note: The valid values for type are "script
", "script attribute
",
"style
", and "style attribute
".
-
Assert: element is not null.
-
Let result be "
Allowed
". -
For each policy of element’s
Document
’s global object’s CSP list:-
For each directive of policy’s directive set:
-
If directive’s inline check returns "
Allowed
" when executed upon element, type, policy and source, skip to the next directive. -
Let directive-name be the result of executing § 6.8.2 Get the effective directive for inline checks on type.
-
Otherwise, let violation be the result of executing § 2.4.1 Create a violation object for global, policy, and directive on the current settings object’s global object, policy, and directive-name.
-
Set violation’s resource to "
inline
". -
Set violation’s element to element.
-
If directive’s value contains the expression "
'report-sample'
", then set violation’s sample to the substring of source containing its first 40 characters. -
Execute § 5.5 Report a violation on violation.
-
If policy’s disposition is "
enforce
", then set result to "Blocked
".
-
-
-
Return result.
4.2.4. Should navigation request of type be blocked by Content Security Policy?
Given a request navigation request and a string type (either
"form-submission
" or "other
"), this algorithm return "Blocked
" if the active policy blocks
the navigation, and "Allowed
" otherwise:
-
Let result be "
Allowed
". -
For each policy of navigation request’s policy container’s CSP list:
-
For each directive of policy:
-
If directive’s pre-navigation check returns "
Allowed
" when executed upon navigation request, type, and policy skip to the next directive. -
Otherwise, let violation be the result of executing § 2.4.1 Create a violation object for global, policy, and directive on navigation request’s client’s global object, policy, and directive’s name.
-
Execute § 5.5 Report a violation on violation.
-
If policy’s disposition is "
enforce
", then set result to "Blocked
".
-
-
-
If result is "
Allowed
", and if navigation request’s current URL’s scheme isjavascript
:-
For each policy of navigation request’s policy container’s CSP list:
-
For each directive of policy:
-
Let directive-name be the result of executing § 6.8.2 Get the effective directive for inline checks on "
navigation
". -
If directive’s inline check returns "
Allowed
" when executed upon null, "navigation
" and navigation request’s current URL, skip to the next directive. -
Otherwise, let violation be the result of executing § 2.4.1 Create a violation object for global, policy, and directive on navigation request’s client’s global object, policy, and directive-name.
-
Set violation’s resource to "
inline
". -
Execute § 5.5 Report a violation on violation.
-
If policy’s disposition is "
enforce
", then set result to "Blocked
".
-
-
-
-
Return result.
4.2.5. Should navigation response to navigation request of type in target be blocked by Content Security Policy?
Given a request navigation request, a response navigation
response, a CSP list response CSP list, a string type (either
"form-submission
" or "other
"), and a navigable target, this algorithm
returns "Blocked
" if the active policy blocks the navigation, and "Allowed
"
otherwise:
-
Let result be "
Allowed
". -
For each policy of response CSP list:
Note: Some directives (like frame-ancestors) allow a response’s Content Security Policy to act on the navigation.
-
For each directive of policy:
-
If directive’s navigation response check returns "
Allowed
" when executed upon navigation request, type, navigation response, target, "response
", and policy skip to the next directive. -
Otherwise, let violation be the result of executing § 2.4.1 Create a violation object for global, policy, and directive on null, policy, and directive’s name.
Note: We use null for the global object, as no global exists: we haven’t processed the navigation to create a Document yet.
-
Execute § 5.5 Report a violation on violation.
-
If policy’s disposition is "
enforce
", then set result to "Blocked
".
-
-
-
For each policy of navigation request’s policy container’s CSP list:
Note: Some directives in the navigation request’s context (like frame-ancestors) need the response before acting on the navigation.
-
For each directive of policy:
-
If directive’s navigation response check returns "
Allowed
" when executed upon navigation request, type, navigation response, target, "source
", and policy skip to the next directive. -
Otherwise, let violation be the result of executing § 2.4.1 Create a violation object for global, policy, and directive on navigation request’s client’s global object, policy, and directive’s name.
-
Execute § 5.5 Report a violation on violation.
-
If policy’s disposition is "
enforce
", then set result to "Blocked
".
-
-
-
Return result.
4.2.6.
Run CSP
initialization for a global object
Given a global object global, the user agent performs the
following steps in order to initialize CSP for global. This algorithm
returns "Allowed
" if global is allowed, and "Blocked
" otherwise:
-
Let result be "
Allowed
". -
For each policy of global’s CSP list:
-
For each directive of policy:
-
Execute directive’s initialization algorithm on global. If its returned value is "
Blocked
", then set result to "Blocked
".
-
-
-
Return result.
4.3. Integration with WebRTC
The administratively-prohibited algorithm calls § 4.3.1 Should RTC connections be blocked for global?
when invoked, and prohibits all candidates if it returns "Blocked
".
4.3.1. Should RTC connections be blocked for global?
Given a global object global, this algorithm returns "Blocked
"
if the active policy for global blocks RTC connections, and "Allowed
" otherwise:
-
Let result be "
Allowed
". -
For each policy of global’s CSP list:
-
For each directive of policy:
-
If directive’s webrtc pre-connect check returns "
Allowed
", continue. -
Otherwise, let violation be the result of executing § 2.4.1 Create a violation object for global, policy, and directive on global, policy, and directive’s name.
-
Set violation’s resource to null.
-
Execute § 5.5 Report a violation on violation.
-
If policy’s disposition is "
enforce
", then set result to "Blocked
".
-
-
-
Return result.
4.4. Integration with ECMAScript
ECMAScript defines a HostEnsureCanCompileStrings()
abstract operation
which allows the host environment to block the compilation of strings into
ECMAScript code. This document defines an implementation of that abstract
operation which examines the relevant CSP list
to determine whether such compilation ought to be blocked.
4.4.1. EnsureCSPDoesNotBlockStringCompilation(realm, parameterStrings, bodyString, codeString, compilationType, parameterArgs, bodyArg)
Given a realm realm, a list of strings parameterStrings, a string bodyString, a string codeString, an enum (compilationType),
a list of ECMAScript language values (parameterArgs), and an ECMAScript language value (bodyArg), this algorithm
returns normally if string compilation is allowed, and throws an "EvalError
"
if not:
-
If compilationType is "
TIMER
", then:-
Let sourceString be codeString.
-
-
Else:
-
Let compilationSink be "Function" if compilationType is "
FUNCTION
", and "eval" otherwise. -
Let isTrusted be
true
if bodyArg implementsTrustedScript
, andfalse
otherwise. -
If isTrusted is
true
then:-
If bodyString is not equal to bodyArg’s data, set isTrusted to
false
.
-
-
If isTrusted is
true
, then:-
Assert: parameterArgs’ [list/size=] is equal to [parameterStrings]' size.
-
For each index of the range 0 to |parameterArgs]' [list/size=]:
-
Let arg be parameterArgs[index].
-
If arg implements
TrustedScript
, then:-
if parameterStrings[index] is not equal to arg’s data, set isTrusted to
false
.
-
-
Otherwise, set isTrusted to
false
.
-
-
-
Let sourceToValidate be a new
TrustedScript
object created in realm whose data is set to codeString if isTrusted istrue
, and codeString otherwise. -
Let sourceString be the result of executing the Get Trusted Type compliant string algorithm, with
TrustedScript
, realm, sourceToValidate, compilationSink, and'script'
. -
If the algorithm throws an error, throw an
EvalError
. -
If sourceString is not equal to codeString, throw an
EvalError
.
-
-
Let result be "
Allowed
". -
Let global be realm’s global object.
-
For each policy of global’s CSP list:
-
Let source-list be null.
-
If policy contains a directive whose name is "
script-src
", then set source-list to that directive’s value.Otherwise if policy contains a directive whose name is "
default-src
", then set source-list to that directive’s value. -
If source-list is not null:
-
Let trustedTypesRequired be the result of executing Does sink type require trusted types?, with realm,
'script'
, andfalse
. -
If trustedTypesRequired is
true
and source-list contains a source expression which is an ASCII case-insensitive match for the string "'trusted-types-eval'
", then skip the following steps. -
If source-list contains a source expression which is an ASCII case-insensitive match for the string "
'unsafe-eval'
", then skip the following steps. -
Let violation be the result of executing § 2.4.1 Create a violation object for global, policy, and directive on global, policy, and "
script-src
". -
Set violation’s resource to "
eval
". -
If source-list contains the expression "
'report-sample'
", then set violation’s sample to the substring of sourceString containing its first 40 characters. -
Execute § 5.5 Report a violation on violation.
-
If policy’s disposition is "
enforce
", then set result to "Blocked
".
-
-
-
If result is "
Blocked
", throw anEvalError
exception.
4.5. Integration with WebAssembly
WebAssembly defines the HostEnsureCanCompileWasmBytes()
abstract operation
which allows the host environment to block the compilation of WebAssembly
sources into executable code. This document defines an implementation of this
abstract operation which examines the relevant CSP
list to determine whether such compilation ought to be blocked.
4.5.1. EnsureCSPDoesNotBlockWasmByteCompilationrealm
Given a realm realm,
this algorithm returns normally if compilation is allowed, and throws a
WebAssembly.CompileError
if not:
-
Let global be realm’s global object.
-
Let result be "
Allowed
". -
For each policy of global’s CSP list:
-
Let source-list be null.
-
If policy contains a directive whose name is "
script-src
", then set source-list to that directive’s value.Otherwise if policy contains a directive whose name is "
default-src
", then set source-list to that directive’s value. -
If source-list is non-null, and does not contain a source expression which is an ASCII case-insensitive match for the string "
'unsafe-eval'
", and does not contain a source expression which is an ASCII case-insensitive match for the string "'wasm-unsafe-eval'
", then:-
Let violation be the result of executing § 2.4.1 Create a violation object for global, policy, and directive on global, policy, and "
script-src
". -
Set violation’s resource to "
wasm-eval
". -
Execute § 5.5 Report a violation on violation.
-
If policy’s disposition is "
enforce
", then set result to "Blocked
".
-
-
-
If result is "
Blocked
", throw aWebAssembly.CompileError
exception.
5. Reporting
When one or more of a policy’s directives is violated, a csp violation report may be generated and sent out to a reporting endpoint associated with the policy.
csp violation reports have the report type "csp-violation".
csp violation reports are visible to
ReportingObserver
s.
dictionary :
CSPViolationReportBody ReportBody {USVString ;
documentURL USVString ?;
referrer USVString ?;
blockedURL DOMString ;
effectiveDirective DOMString ;
originalPolicy USVString ?;
sourceFile DOMString ?;
sample SecurityPolicyViolationEventDisposition ;
disposition unsigned short ;
statusCode unsigned long ?;
lineNumber unsigned long ?; };
columnNumber
When a directive that impacts script-like destinations has a report-sha256
,
report-sha384
or report-sha512
value, and a request with a script-like
destination is fetched, a csp hash report will be generated and
sent out to a reporting endpoint associated with the policy.
csp hash reports have the report type "csp-hash".