From 6638ad4a69933fe824575edf96348c6ec6eb7251 Mon Sep 17 00:00:00 2001
From: Yoav Weiss " "" "" Fetches for the following code will all return network errors, as the URLs
provided do not match Assert: policy is unused. If request’s initiator is " If request’s initiator is " If the result of executing §6.6.1.3 Does request match source list? on request and this directive’s value is
@@ -3191,8 +3187,7 @@ Assert: policy is unused. If request’s initiator is " If request’s initiator is " If the result of executing §6.6.1.4 Does response to request match source list? on response, request, and this directive’s value is " Fetches for the following code will return a network errors, as the URL
provided do not match Assert: policy is unused. If request’s type is " If request’s destination is " If the result of executing §6.6.1.3 Does request match source list? on request and this directive’s value is
@@ -3337,7 +3332,7 @@ Assert: policy is unused. If request’s type is " If request’s destination is " If the result of executing §6.6.1.4 Does response to request match source list? on response, request, and this directive’s value is " Assert: policy is unused. If request’s type is " If request’s destination is " Assert: policy is unused. If request’s type is " If request’s destination is " This directive controls requests which load images. More formally, this
- includes requests whose type is " Assert: policy is unused. If request’s type is " If request’s destination is " If the result of executing §6.6.1.3 Does request match source list? on request and this directive’s value is
@@ -3437,7 +3432,7 @@ Assert: policy is unused. If request’s type is " If request’s destination is " If the result of executing §6.6.1.4 Does response to request match source list? on response, request, and this directive’s value is " Assert: policy is unused. If request’s type is "", and its initiator is " If request’s destination is " If the result of executing §6.6.1.3 Does request match source list? on request and this directive’s value is
@@ -3485,7 +3480,7 @@ Assert: policy is unused. If request’s type is "", and its initiator is " If request’s destination is " If the result of executing §6.6.1.4 Does response to request match source list? on response, request, and this directive’s value is " Fetches for the following code will return a network errors, as the URL
provided do not match Assert: policy is unused. If request’s type is one of " If request’s destination is one of " Assert: policy is unused. If request’s type is one of " If request’s destination is one of " Fetches for the following code will return a network errors, as the URL
provided do not match If plugin content is loaded without an associated URL (perhaps an Assert: policy is unused. If request’s type is "", and its destination is " If request’s destination is " If the result of executing §6.6.1.3 Does request match source list? on request and this directive’s value is
@@ -3604,7 +3599,7 @@ Assert: policy is unused. If request’s type is "", and its destination is " If request’s destination is " If the result of executing §6.6.1.4 Does response to request match source list? on response, request, and this directive’s value is "Content Security Policy Level 3
- Editor’s Draft,
+ Editor’s Draft,
report
"
child-src
's source list:<iframe src="https://not-example.com"></iframe>
-<script>
- var blockedWorker = new Worker("data:application/javascript,...");
+
<iframe src="https://not-example.com"></iframe>
+<script>
+ var blockedWorker = new Worker("data:application/javascript,...");
</script>
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://not-example.com">...
-<script>
- var xhr = new XMLHttpRequest();
- xhr.open('GET', 'https://not-example.com/');
- xhr.send();
+<script>
+ var xhr = new XMLHttpRequest();
+ xhr.open('GET', 'https://not-example.com/');
+ xhr.send();
- var ws = new WebSocket("https://not-example.com/");
+ var ws = new WebSocket("https://not-example.com/");
- var es = new EventSource("https://not-example.com/");
+ var es = new EventSource("https://not-example.com/");
- navigator.sendBeacon("https://not-example.com/", { ... });
+ navigator.sendBeacon("https://not-example.com/", { ... });
</script>
fetch
", or its type is "" and destination is
- "":fetch
" or its destination is "":
fetch
", or its type is "" and destination is
- "subresource
":fetch
" or its destination is "":
Does Not Match
", return
@@ -3303,10 +3298,10 @@
font-src
's source list:<style>
+
<style>
@font-face {
font-family: "Example Font";
- src: url("https://not-example.com/font");
+ src: url("https://not-example.com/font");
}
body {
font-family: "Example Font";
@@ -3321,7 +3316,7 @@
font
":font
":
font
":font
":
Does Not Match
", return
@@ -3369,7 +3364,7 @@
document
" and target browsing context is a nested browsing
+ document
" and target browsing context is a nested browsing
context:
document
" and target browsing context is a nested browsing
+ document
" and target browsing context is a nested browsing
context:
serialized-source-list
image
" [FETCH].image
" [FETCH].Content-Security-Policy: img-src https://example.com/
@@ -3421,7 +3416,7 @@
image
":image
":
image
":image
":
Does Not Match
", return
@@ -3469,7 +3464,7 @@
manifest
":manifest
":
manifest
":manifest
":
Does Not Match
", return
@@ -3507,7 +3502,7 @@
media-src
's source list:<audio src="https://not-example.com/audio"></audio>
+
<audio src="https://not-example.com/audio"></audio>
<video src="https://not-example.com/video">
<track kind="subtitles" src="https://not-example.com/subtitles">
</video>
@@ -3520,7 +3515,7 @@
audio
", "video
",
+ audio
", "video
",
or "track
":
audio
", "video
",
+ audio
", "video
",
or "track
":
object-src
's source list:<embed src="https://not-example.com/flash"></embed>
-<object data="https://not-example.com/flash"></object>
-<applet archive="https://not-example.com/flash"></applet>
+
<embed src="https://not-example.com/flash"></embed>
+<object data="https://not-example.com/flash"></object>
+<applet archive="https://not-example.com/flash"></applet>
object
element lacks a data
attribute, but loads some default plugin based
@@ -3588,7 +3583,7 @@
unknown
":object
" or "embed
":
unknown
":object
" or "embed
":
Does Not Match
", return
@@ -3656,7 +3651,7 @@ §6.6.1.11 Get the effective directive for request on request is "
worker-src
", and policy contains a directive whose name is "worker-src
", return "Allowed
".
Note: If worker-src
is present, we’ll defer to it when handling worker requests.
If request’s type is "script
":
If request’s destination is a script-like destination:
If the result of executing §6.6.1.2 Does nonce match source list? on request’s cryptographic nonce metadata and this @@ -3719,7 +3714,7 @@
worker-src
", and policy contains a directive whose name is "worker-src
", return "Allowed
".
Note: If worker-src
is present, we’ll defer to it when handling worker requests.
If request’s type is "script
":
If request’s destination is a script-like destination:
If the result of executing §6.6.1.2 Does nonce match source list? on request’s cryptographic nonce metadata and this @@ -3826,7 +3821,7 @@
Assert: policy is unused.
If request’s type is "style
":
If request’s destination is "style
":
If the result of executing §6.6.1.2 Does nonce match source list? on request’s cryptographic nonce metadata and this @@ -3846,7 +3841,7 @@
Assert: policy is unused.
If request’s type is "style
":
If request’s destination is "style
":
If the result of executing §6.6.1.2 Does nonce match source list? on request’s cryptographic nonce metadata and this @@ -3890,10 +3885,10 @@
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://not-example.com/"); - navigator.serviceWorker.register('https://not-example.com/sw.js'); +<script> + var blockedWorker = new Worker("data:application/javascript,..."); + blockedWorker = new SharedWorker("https://not-example.com/"); + navigator.serviceWorker.register('https://not-example.com/sw.js'); </script>@@ -4002,21 +3997,21 @@Content-Security-Policy: plugin-types application/pdf
Fetches for the following code will all return network errors:
-<!-- No 'type' declaration --> -<object data="https://example.com/flash"></object> +<!-- No 'type' declaration --> +<object data="https://example.com/flash"></object> -<!-- Non-matching 'type' declaration --> -<object data="https://example.com/flash" type="application/x-shockwave-flash"></object> +<!-- Non-matching 'type' declaration --> +<object data="https://example.com/flash" type="application/x-shockwave-flash"></object> -<!-- Non-matching resource --> -<object data="https://example.com/flash" type="application/pdf"></object> +<!-- Non-matching resource --> +<object data="https://example.com/flash" type="application/pdf"></object>If the page allowed Flash content by sending the following header:
Content-Security-Policy: plugin-types application/x-shockwave-flashThen the second item above would load successfully:
-<!-- Matching 'type' declaration and resource --> -<object data="https://example.com/flash" type="application/x-shockwave-flash"></object> +<!-- Matching 'type' declaration and resource --> +<object data="https://example.com/flash" type="application/x-shockwave-flash"></object>6.2.2.1.
@@ -4600,31 +4595,38 @@plugin-types
Post-Request CheckReturn "
Matches
".
Each fetch directive controls a specific type of request. Given +
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:
Switch on request’s type, and execute +
Switch on request’s destination, and execute the associated steps:
If the request’s initiator and destination are both the empty string, return connect-src
.
If the request’s initiator is
- "manifest
", return manifest-src
.
connect-src
.
+ manifest
"
+ If the request’s destination is
- "subresource
", return connect-src
.
Return manifest-src
.
object
"
+ embed
"
+ If the request’s destination is
- "unknown
", return object-src
.
Return object-src
.
document
"
+ If the request’s destination is
- "document
" and the request’s target browsing context is a nested browsing
- context, return frame-src
.
If the request’s target browsing context is a nested browsing context, return frame-src
.
audio
"
track
"
@@ -4653,28 +4655,18 @@ script
"
+ xslt
"
Switch on request’s destination, and - execute the associated steps:
-script
"
- subresource
"
- Return script-src
.
serviceworker
"
- sharedworker
"
- worker
"
- Return worker-src
.
Return script-src
.
sharedworker
"
+ worker
"
+ Return worker-src
.
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> +<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> +<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 asrc
attribute pointing to a malicious payload, an attribute named</p>
, @@ -4873,11 +4865,11 @@
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 loadhttps://example.com/good.js
: -<script nonce=abc src=/good.js></script> +<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> +<script nonce=abc src=/good.js></script>To mitigate this risk, it is advisable to set an explicit
@@ -4992,17 +4984,17 @@base
element on every page, or to limit the ability of an attacker to inject their ownbase
element by setting abase-uri
directive in your page’s policy. For example,base-uri 'none'
.
And serves the following HTML with that policy active:
... -<script src="https://cdn.example.com/script.js" nonce="DhcnhD3khTMePgXwdayK9BsMqXjhguVV" ></script> +<script src="https://cdn.example.com/script.js" nonce="DhcnhD3khTMePgXwdayK9BsMqXjhguVV" ></script> ...This will generate a request for
https://cdn.example.com/script.js
, which will not be blocked because of the matchingnonce
attribute.If
-script.js
contains the following code:var s = document.createElement('script'); +var s = document.createElement('script'); s.src = 'https://othercdn.not-example.net/dependency.js'; -document.head.appendChild('s'); +document.head.appendChild('s'); -document.write('<scr' + 'ipt src='/sadness.js'></scr' + 'ipt>'); +document.write('<scr' + 'ipt src='/sadness.js'></scr' + 'ipt>');
dependency.js
will load, as thescript
element created bycreateElement()
is not "parser-inserted".@@ -5052,16 +5044,16 @@
sadness.js
will not load, however, asdocument.write()
producesscript
elements which are "parser-inserted".script elements would be allowed to execute because they contain only integrity metadata that matches the policy: -
<script integrity="sha256-abc123" ...></script> -<script integrity="sha512-321cba" ...></script> -<script integrity="sha256-abc123 sha512-321cba" ...></script> +<script integrity="sha256-abc123" ...></script> +<script integrity="sha512-321cba" ...></script> +<script integrity="sha256-abc123 sha512-321cba" ...></script>While the following
-script
elements would not execute because they contain valid metadata that does not match the policy (even though other metadata does match):<script integrity="sha384-xyz789" ...></script> -<script integrity="sha384-xyz789 sha512-321cba" ...></script> -<script integrity="sha256-abc123 sha384-xyz789 sha512-321cba" ...></script> +<script integrity="sha384-xyz789" ...></script> +<script integrity="sha384-xyz789 sha512-321cba" ...></script> +<script integrity="sha256-abc123 sha384-xyz789 sha512-321cba" ...></script>Metadata that is not recognized (either because it’s entirely invalid, or because it specifies a not-yet-supported hashing algorithm) does not affect @@ -5069,9 +5061,9 @@