8. Authoring Considerations
8.1. The effect of multiple policies
- This section is not normative.
- The above sections note that when multiple policies are present, each must be
+ This section is not normative. The above sections note that when multiple policies are present, each must be
enforced or reported, according to its type. An example will help clarify how
that ought to work in practice. The behavior of an XMLHttpRequest
might seem unclear given a site that, for whatever reason, delivered the
- following HTTP headers:
+ following HTTP headers:
Content-Security-Policy: default-src 'self' http://example.com http://example.net;
@@ -4512,108 +4562,111 @@
- Is a connection to example.com allowed or not? The short answer is that the
+ Is a connection to example.com allowed or not? The short answer is that the
connection is not allowed. Enforcing both policies means that a potential
connection would have to pass through both unscathed. Even though the second
policy would allow this connection, the first policy contains connect-src 'none'
, so its enforcement blocks the connection. The
impact is that adding additional policies to the list of policies to enforce
- can only further restrict the capabilities of the protected resource.
- To demonstrate that further, consider a script tag on this page. The first
+ can only further restrict the capabilities of the protected resource.
+
+ To demonstrate that further, consider a script tag on this page. The first
policy would lock scripts down to 'self'
, http://example.com
and http://example.net
via the default-src
directive. The second, however,
would only allow script from http://example.com/
. Script will only load if
it meets both policy’s criteria: in this case, the only origin that can match
- is http://example.com
, as both policies allow it.
+ is http://example.com
, as both policies allow it.
8.2. Usage of "'strict-dynamic'
"
- Whitelists are tough to get right, especially on sprawling origins like CDNs.
+ Whitelists are tough to get right, especially on sprawling origins like CDNs.
The solutions
to Cure53’s H5SC Minichallenge 3: "Sh*t, it’s CSP!" [H5SC3] are good
examples of the kinds of bypasses which whitelists can enable, and though CSP
is capable of mitigating these bypasses via extensive whitelists, those end
- up being brittle, awkward, and difficult to implement and maintain.
- The "'strict-dynamic'
" source expression aims to make Content
+ up being brittle, awkward, and difficult to implement and maintain.
+
+ The "'strict-dynamic'
" source expression aims to make Content
Security Policy simpler to deploy for existing applications who have a high
degree of confidence in the scripts they load directly, but low confidence in
- their ability to provide a reasonably secure whitelist.
- If present in a script-src
or default-src
directive, it has
- two main effects:
-
- -
-
host-source and scheme-source expressions, as well as the "'unsafe-inline'
"
- and "'self'
keyword-sources will be
- ignored when loading script.
- hash-source and nonce-source expressions
- will be honored.
- -
-
Script requests which are triggered by non-"parser-inserted" script
elements are allowed.
-
- The first change allows you to deploy "'strict-dynamic'
in a
- backwards compatible way, without requiring user-agent sniffing: the policy 'unsafe-inline' https: 'nonce-abcdefg' 'strict-dynamic'
will act like 'unsafe-inline' https:
in browsers that support CSP1, https: 'nonce-abcdefg'
in browsers that support CSP2, and 'nonce-abcdefg' 'strict-dynamic'
in browsers that support CSP3.
- The second allows scripts which are given access to the page via nonces or
+ their ability to provide a reasonably secure whitelist.
+
+ If present in a script-src
or default-src
directive, it has
+ two main effects:
+
+ 1. host-source and scheme-source expressions, as well as the "'unsafe-inline'
"
+ and "'self'
keyword-sources will be
+ ignored when loading script. hash-source and nonce-source expressions
+ will be honored.
+
+ 2. Script requests which are triggered by non-"parser-inserted" script
elements are allowed.
+
+ The first change allows you to deploy "'strict-dynamic'
in a
+ backwards compatible way, without requiring user-agent sniffing: the policy 'unsafe-inline' https: 'nonce-abcdefg' 'strict-dynamic'
will act like 'unsafe-inline' https:
in browsers that support CSP1, https: 'nonce-abcdefg'
in browsers that support CSP2, and 'nonce-abcdefg' 'strict-dynamic'
in browsers that support CSP3.
+
+ The second allows scripts which are given access to the page via nonces or
hashes to bring in their dependencies without adding them explicitly to the
- page’s policy.
-
-
Suppose MegaCorp, Inc. deploys the following policy:
+ page’s policy.
+
+
Suppose MegaCorp, Inc. deploys the following policy:
: script-src 'nonce-abcdefg' 'strict-dynamic'
-
And serves the following HTML with that policy active:
+ And serves the following HTML with that policy active:
...
<script src="https://cdn.example.com/script.js" nonce="abcdefg" ></script>
...
-
This will generate a request for https://cdn.example.com/script.js
, which
- will not be blocked because of the matching nonce
attribute.
-
If script.js
contains the following code:
+ This will generate a request for
https://cdn.example.com/script.js
, which
+ will not be blocked because of the matching
nonce
attribute.
+
+ If
script.js
contains the following code:
var s = document.createElement('script');
s.src = 'https://othercdn.not-example.net/dependency.js';
document.head.appendChild('s');
document.write('<scr' + 'ipt src='/sadness.js'></scr' + 'ipt>');
-
dependency.js
will load, as the script
element created by createElement()
is not "parser-inserted".
-
sadness.js
will not load, however, as document.write()
produces script
elements which are "parser-inserted".
+
dependency.js
will load, as the
script
element created by
createElement()
is not
"parser-inserted".
sadness.js
will
not load, however, as
document.write()
produces
script
elements which are
"parser-inserted".
8.3. Usage of "'unsafe-hashed-attributes'
"
-
This section is not normative.
-
Legacy websites and websites with legacy dependencies might find it difficult
+ This section is not normative. Legacy websites and websites with legacy dependencies might find it difficult
to entirely externalize event handlers. These sites could enable such handlers
by whitelisting 'unsafe-inline'
, but that’s a big hammer with a lot of
- associated risk (and cannot be used in conjunction with nonces or hashes).
-
The "'unsafe-hashed-attributes'
" source expression aims to make
+ associated risk (and cannot be used in conjunction with nonces or hashes).
+
+ The "'unsafe-hashed-attributes'
" source expression aims to make
CSP deployment simpler and safer in these situations by allowing developers
- to whitelist specific handlers via hashes.
-
-
MegaCorp, Inc. can’t quite get rid of the following HTML on anything
+ to whitelist specific handlers via hashes.
+
+
MegaCorp, Inc. can’t quite get rid of the following HTML on anything
resembling a reasonable schedule:
<button id="action" onclick="doSubmit()">
-
Rather than whitelisting "'unsafe-inline'
", they decide to use
- "'unsafe-hashed-attributes'
" along with a hash source expression, as follows:
+ Rather than whitelisting "
'unsafe-inline'
", they decide to use
+ "
'unsafe-hashed-attributes'
" along with a hash source expression, as follows:
: script-src 'unsafe-hashed-attributes' 'sha256-jzgBGA4UWFFmpOBq0JpdsySukE1FrEN5bUpoK8Z29fY='
8.4. Whitelisting external JavaScript with hashes
-
This section is not normative.
-
In [CSP2], hash source expressions could only whitelist inlined
+ This section is not normative. In [CSP2], hash source expressions could only whitelist inlined
script, but now that Subresource Integrity is widely deployed, we can expand
- the scope to enable externalized JavaScript as well.
-
If multiple sets of integrity metadata are specified for a script
, the
- request will match a policy’s hash-sources if and only if each item in a script
's integrity metadata matches the policy.
-
-
MegaCorp, Inc. wishes to whitelist two specific scripts on a page in a way
+ the scope to enable externalized JavaScript as well.
+
+
+ If multiple sets of integrity metadata are specified for a
script
, the
+ request will match a policy’s
hash-sources if and only if
each item in a
script
's integrity metadata matches the policy.
+
+
MegaCorp, Inc. wishes to whitelist two specific scripts on a page in a way
that ensures that the content matches their expectations. They do so by
setting the following policy:
Content-Security-Policy: script-src 'sha256-abc123' 'sha512-321cba'
-
In the presence of that policy, the following script
elements would be
+ In the presence of that policy, the following script
elements would be
whitelisted because they contain only integrity metadata that matches the
- policy:
+ policy:
<script integrity="sha256-abc123" ...></script>
<script integrity="sha512-321cba" ...></script>
<script integrity="sha256-abc123 sha512-321cba" ...></script>
-
While the following script
elements would not be whitelisted because they
+ While the following script
elements would not be whitelisted because they
contain metadata that does not match the policy (even though other metadata
- does match):
+ does match):
<script integrity="sha384-xyz789" ...></script>
<script integrity="sha384-xyz789 sha512-321cba" ...></script>
<script integrity="sha256-abc123 sha384-xyz789 sha512-321cba" ...></script>
@@ -4623,107 +4676,48 @@ 9. Implementation Considerations
9.1. Vendor-specific Extensions and Addons
- Policy enforced on a resource SHOULD NOT interfere with the operation
+ Policy enforced on a resource SHOULD NOT interfere with the operation
of user-agent features like addons, extensions, or bookmarklets. These kinds
of features generally advance the user’s priority over page authors, as
- espoused in [HTML-DESIGN].
- Moreover, applying CSP to these kinds of features produces a substantial
+ espoused in [HTML-DESIGN].
+
+ Moreover, applying CSP to these kinds of features produces a substantial
amount of noise in violation reports, significantly reducing their value to
- developers.
- Chrome, for example, excludes the chrome-extension:
scheme from CSP checks,
+ developers.
+
+ Chrome, for example, excludes the chrome-extension:
scheme from CSP checks,
and does some work to ensure that extension-driven injections are allowed,
- regardless of a page’s policy.
+ regardless of a page’s policy.
10. IANA Considerations
10.1. Directive Registry
- The Content Security Policy Directive registry should be updated with the
- following directives and references [RFC7762]:
-
- -
-
base-uri
- -
-
This document (see §6.2.1 base-uri)
- -
-
child-src
- -
-
This document (see §6.1.1 child-src)
- -
-
connect-src
- -
-
This document (see §6.1.2 connect-src)
- -
-
default-src
- -
-
This document (see §6.1.3 default-src)
- -
-
disown-opener
- -
-
This document (see §6.2.4 disown-opener)
- -
-
font-src
- -
-
This document (see §6.1.4 font-src)
- -
-
form-action
- -
-
This document (see §6.3.1 form-action)
- -
-
frame-ancestors
- -
-
This document (see §6.3.2 frame-ancestors)
- -
-
frame-src
- -
-
This document (see §6.1.5 frame-src)
- -
-
img-src
- -
-
This document (see §6.1.6 img-src)
- -
-
manifest-src
- -
-
This document (see §6.1.7 manifest-src)
- -
-
media-src
- -
-
This document (see §6.1.8 media-src)
- -
-
object-src
- -
-
This document (see §6.1.9 object-src)
- -
-
plugin-types
- -
-
This document (see §6.2.2 plugin-types)
- -
-
report-uri
- -
-
This document (see §6.4.1 report-uri)
- -
-
report-to
- -
-
This document (see §6.4.2 report-to)
- -
-
sandbox
- -
-
This document (see §6.2.3 sandbox)
- -
-
script-src
- -
-
This document (see §6.1.10 script-src)
- -
-
style-src
- -
-
This document (see §6.1.11 style-src)
- -
-
worker-src
- -
-
This document (see §6.1.12 worker-src)
-
+ The Content Security Policy Directive registry should be updated with the
+ following directives and references [RFC7762]:
+
+ : base-uri
:: This document (see §6.2.1 base-uri)
+ : child-src
:: This document (see §6.1.1 child-src)
+ : connect-src
:: This document (see §6.1.2 connect-src)
+ : default-src
:: This document (see §6.1.3 default-src)
+ : disown-opener
:: This document (see §6.2.4 disown-opener)
+ : font-src
:: This document (see §6.1.4 font-src)
+ : form-action
:: This document (see §6.3.1 form-action)
+ : frame-ancestors
:: This document (see §6.3.2 frame-ancestors)
+ : frame-src
:: This document (see §6.1.5 frame-src)
+ : img-src
:: This document (see §6.1.6 img-src)
+ : manifest-src
:: This document (see §6.1.7 manifest-src)
+ : media-src
:: This document (see §6.1.8 media-src)
+ : object-src
:: This document (see §6.1.9 object-src)
+ : plugin-types
:: This document (see §6.2.2 plugin-types)
+ : report-uri
:: This document (see §6.4.1 report-uri)
+ : report-to
:: This document (see §6.4.2 report-to)
+ : sandbox
:: This document (see §6.2.3 sandbox)
+ : script-src
:: This document (see §6.1.10 script-src)
+ : style-src
:: This document (see §6.1.11 style-src)
+ : worker-src
:: This document (see §6.1.12 worker-src)
- The permanent message header field registry should be updated
- with the following registrations: [RFC3864]
+ The permanent message header field registry should be updated
+ with the following registrations: [RFC3864]
10.2.1. Content-Security-Policy
- Header field name
@@ -4753,14 +4747,12 @@
11. Acknowledgements
- Lots of people are awesome. For instance:
-
- -
-
Mario and all of Cure53.
- -
-
Artur Janc, Michele Spagnuolo, Lukas Weichselbaum, Jochen Eisinger, and the
-rest of Google’s CSP Cabal.
-
+ Lots of people are awesome. For instance:
+
+ * Mario and all of Cure53.
+
+ * Artur Janc, Michele Spagnuolo, Lukas Weichselbaum, Jochen Eisinger, and the
+ rest of Google’s CSP Cabal.
@@ -5194,6 +5186,8 @@
What should this do in an
iframe
? Anything?
↵
+
This processing is meant to mitigate the risk
+ of dangling markup attacks that steal the nonce from an existing element
+ in order to load injected script. It is fairly expensive, however, as it
+ requires that we walk through all attributes and their values in order to
+ determine whether the script should execute. Here, we try to minimize the
+ impact by doing this check only for
script
elements when a nonce is
+ present, but we should probably consider this algorithm as "at risk" until
+ we know its impact.
<https://github.com/w3c/webappsec-csp/issues/98> ↵
@@ -5777,7 +5779,7 @@
(2) (3)
6.6.1.6.
Does url match expression in origin with redirect count?
- 6.6.2.1.
+ 6.6.2.2.
Does element match source list for type and source?
8.4.
Whitelisting external JavaScript with hashes
@@ -5883,7 +5885,7 @@ 6.1.10.3.
script-src Inline Check
(2) (3)
- 6.6.2.1.
+ 6.6.2.2.
Does element match source list for type and source?
8.2.
Usage of "'strict-dynamic'"
@@ -5934,7 +5936,7 @@ 6.1.10.3.
script-src Inline Check
- 6.6.2.1.
+ 6.6.2.2.
Does element match source list for type and source? (2)
8.3.
Usage of "'unsafe-hashed-attributes'" (2)
@@ -5949,9 +5951,11 @@ 6.6.1.2.
Does nonce match source list?
6.6.2.1.
- Does element match source list for type and source? (2) (3)
- 7.1. Nonce Reuse
- 8.2.
+ Is element nonceable?
+ 6.6.2.2.
+ Does element match source list for type and source? (2) (3)
+ 7.1. Nonce Reuse
+ 8.2.
Usage of "'strict-dynamic'"
@@ -5963,7 +5967,7 @@ 6.6.1.2.
Does nonce match source list?
- 6.6.2.1.
+ 6.6.2.2.
Does element match source list for type and source? (2)
@@ -5975,7 +5979,7 @@ 6.1.10.1.
script-src Pre-request check
(2)
6.1.11. style-src
- 6.6.2.1.
+ 6.6.2.2.
Does element match source list for type and source? (2) (3)
8.2.
Usage of "'strict-dynamic'"
@@ -5989,7 +5993,7 @@ 2.2.1. Source Lists
6.1.10.1.
script-src Pre-request check
- 6.6.2.1.
+ 6.6.2.2.
Does element match source list for type and source? (2) (3)
@@ -6328,7 +6332,7 @@ #style-src
Referenced in:
diff --git a/index.src.html b/index.src.html
index a0e301e63c..0a0dc8f3c0 100644
--- a/index.src.html
+++ b/index.src.html
@@ -17,6 +17,7 @@ Content Security Policy Level 3
Boilerplate: omit conformance, omit feedback-header
!Participate: File an issue (open issues)
Markup Shorthands: css off, markdown on
+At Risk: The [[#is-element-nonceable]] algorithm.
spec:dom; type:interface; text:Document
@@ -196,6 +197,12 @@ Content Security Policy Level 3
"title": "Generic cross-browser cross-domain theft",
"authors": [ "Chris Evans" ],
"date": "28 December 2009"
+ },
+ "FILEDESCRIPTOR-2015": {
+ "href": "http://blog.innerht.ml/csp-2015/#danglingmarkupinjection",
+ "title": "CSP 2015",
+ "authors": [ "filedescriptor" ],
+ "date": "23 November 2015"
}
}
@@ -3415,6 +3422,40 @@
Element Matching Algorithms
+
+ Is |element| nonceable?
+
+
+ Given an {{Element}} (|element|), this algorithm returns "`Nonceable`" if
+ a `nonce-source` expression can match the element (as discussed
+ in [[#security-nonce-stealing]]), and "`Not Nonceable`" if such expressions
+ should not be applied.
+
+ 1. If |element| does not have an attribute named "`nonce`", return "`Not
+ Nonceable`".
+
+ 2. If |element| is a <{script}> element, then for each |attribute| in
+ |element|:
+
+ 1. If |attribute|'s name is an ASCII case-insensitive match for
+ the string "`