@@ -2140,6 +2140,14 @@ this algorithm returns normally if compilation is allowed, and throws a
2140
2140
out in more detail in the [[#should-block-request]] and
2141
2141
[[#should-block-response]] algorithms.
2142
2142
2143
+ <div class="note">
2144
+ Resource hints such as [^link/rel/prefetch^] and [^link/rel/dns-prefetch^] generate requests that
2145
+ aren't tied to any specific [=fetch directive=] , but are instead governed by the union of servers
2146
+ allowed in all of a policy's directives' [=source lists=] . If <a>default-src</a> is not specified, these
2147
+ requests will always be allowed. For more information, see [[#exfiltration]] .
2148
+ </div>
2149
+
2150
+
2143
2151
<div class="example">
2144
2152
The following header:
2145
2153
@@ -2156,7 +2164,6 @@ this algorithm returns normally if compilation is allowed, and throws a
2156
2164
<a>img-src</a> <a grammar>'self'</a> ;
2157
2165
<a>manifest-src</a> <a grammar>'self'</a> ;
2158
2166
<a>media-src</a> <a grammar>'self'</a> ;
2159
- <a>prefetch-src</a> <a grammar>'self'</a> ;
2160
2167
<a>object-src</a> <a grammar>'self'</a> ;
2161
2168
<a>script-src-elem</a> <a grammar>'self'</a> ;
2162
2169
<a>script-src-attr</a> <a grammar>'self'</a> ;
@@ -2186,7 +2193,6 @@ this algorithm returns normally if compilation is allowed, and throws a
2186
2193
<a>img-src</a> <a grammar>'self'</a> ;
2187
2194
<a>manifest-src</a> <a grammar>'self'</a> ;
2188
2195
<a>media-src</a> <a grammar>'self'</a> ;
2189
- <a>prefetch-src</a> <a grammar>'self'</a> ;
2190
2196
<a>object-src</a> <a grammar>'self'</a> ;
2191
2197
<a>script-src-elem</a> https://example.com;
2192
2198
<a>script-src-attr</a> <a grammar>'self'</a> ;
@@ -2703,74 +2709,6 @@ this algorithm returns normally if compilation is allowed, and throws a
2703
2709
2704
2710
4. Return "`Allowed`".
2705
2711
2706
- <h4 id="directive-prefetch-src">`prefetch-src`</h4>
2707
-
2708
- The <dfn export>prefetch-src</dfn> directive restricts the URLs from which resources may be
2709
- prefetched or prerendered. The syntax for the directive's name and value is described by the
2710
- following ABNF:
2711
-
2712
- <pre>
2713
- directive-name = "prefetch-src"
2714
- directive-value = <a grammar>serialized-source-list</a>
2715
- </pre>
2716
-
2717
- <div class="example">
2718
- Given a page with the following Content Security Policy:
2719
-
2720
- <pre>
2721
- <a http-header>Content-Security-Policy</a> : <a>prefetch-src</a> https://example.com/
2722
- </pre>
2723
-
2724
- Fetches for the following code will return network errors, as the URLs provided do not match
2725
- `prefetch-src`'s <a>source list</a> :
2726
-
2727
- <pre highlight="html">
2728
- <link rel="prefetch" src="https://example.org/"></link>
2729
- <link rel="prerender" src="https://example.org/"></link>
2730
- </pre>
2731
- </div>
2732
-
2733
- <h5 algorithm id="prefetch-src-pre-request">
2734
- `prefetch-src` Pre-request check
2735
- </h5>
2736
-
2737
- This directive's <a for="directive">pre-request check</a> is as follows:
2738
-
2739
- Given a <a for="/">request</a> (|request|) and a <a for="/">policy</a> (|policy|):
2740
-
2741
- 1. Let |name| be the result of executing [[#effective-directive-for-a-request]]
2742
- on |request|.
2743
-
2744
- 2. If the result of executing [[#should-directive-execute]] on |name|,
2745
- `prefetch-src` and |policy| is "`No`", return "`Allowed`".
2746
-
2747
- 3. If the result of executing [[#match-request-to-source-list]] on |request|,
2748
- this directive's [=directive/value=] , and |policy|,
2749
- is "`Does Not Match`", return "`Blocked`".
2750
-
2751
- 4. Return "`Allowed`".
2752
-
2753
- <h5 algorithm id="prefetch-src-post-request">
2754
- `prefetch-src` Post-request check
2755
- </h5>
2756
-
2757
- This directive's <a for="directive">post-request check</a> is as follows:
2758
-
2759
- Given a <a for="/">request</a> (|request|), a <a>response</a> (|response|), and a
2760
- <a for="/">policy</a> (|policy|):
2761
-
2762
- 1. Let |name| be the result of executing [[#effective-directive-for-a-request]]
2763
- on |request|.
2764
-
2765
- 2. If the result of executing [[#should-directive-execute]] on |name|,
2766
- `prefetch-src` and |policy| is "`No`", return "`Allowed`".
2767
-
2768
- 3. If the result of executing [[#match-response-to-source-list]] on |response|,
2769
- |request|, this directive's [=directive/value=] , and |policy|,
2770
- is "`Does Not Match`", return "`Blocked`".
2771
-
2772
- 4. Return "`Allowed`".
2773
-
2774
2712
<h4 id="directive-script-src">`script-src`</h4>
2775
2713
2776
2714
The <dfn export>script-src</dfn> directive restricts the locations from which scripts
@@ -3794,16 +3732,41 @@ this algorithm returns normally if compilation is allowed, and throws a
3794
3732
algorithm returns the violated <a>directive</a> if the request violates the
3795
3733
policy, and "`Does Not Violate`" otherwise.
3796
3734
3797
- 1. Let |violates| be "`Does Not Violate`".
3735
+ 1. If |request|'s [=request/initiator=] is "`prefetch`", then return the result of executing
3736
+ [[#does-resource-hint-violate-policy]] on |request| and |policy|.
3737
+
3738
+ 2. Let |violates| be "`Does Not Violate`".
3798
3739
3799
- 2 . <a for=set>For each</a> |directive| of |policy|:
3740
+ 3 . <a for=set>For each</a> |directive| of |policy|:
3800
3741
3801
3742
1. Let |result| be the result of executing |directive|'s
3802
3743
<a for="directive">pre-request check</a> on |request| and |policy|.
3803
3744
3804
3745
2. If |result| is "`Blocked`", then let |violates| be |directive|.
3805
3746
3806
- 3. Return |violates|.
3747
+ 4. Return |violates|.
3748
+
3749
+ <h5 id="does-resource-hint-violate-policy">
3750
+ Does resource hint |request| violate |policy|?
3751
+ </h5>
3752
+
3753
+ Given a <a for="/">request</a> (|request|) and a <a for="/">policy</a> (|policy|), this
3754
+ algorithm returns the default <a>directive</a> if the resource-hint request violates all the
3755
+ policies, and "`Does Not Violate`" otherwise.
3756
+
3757
+ 1. Let |defaultDirective| be |policy|'s first [=directive=] whose [=directive/name=] is
3758
+ "`default-src`".
3759
+
3760
+ 2. If |defaultDirective| does not exist, return "`Does Not Violate`".
3761
+
3762
+ 3. <a for=set>For each</a> |directive| of |policy|:
3763
+
3764
+ 1. Let |result| be the result of executing |directive|'s
3765
+ <a for="directive">pre-request check</a> on |request| and |policy|.
3766
+
3767
+ 2. If |result| is "`Allowed`", then return "`Does Not Violate`".
3768
+
3769
+ 4. Return "`Blocked`".
3807
3770
3808
3771
<h5 id="match-nonce-to-source-list" algorithm>
3809
3772
Does |nonce| match |source list|?
@@ -4333,11 +4296,11 @@ this algorithm returns normally if compilation is allowed, and throws a
4333
4296
`null` or the <a for="directive">name</a> of the request's
4334
4297
<dfn for="request" export>effective directive</dfn> :
4335
4298
4336
- 1. If |request|'s <a for=" request">initiator</a> is "`fetch `" or its
4337
- <a for="request">destination</a> is "", return `connect -src`.
4299
+ 1. If |request|'s [= request/initiator=] is "`prefetch `" or "`prerender`",
4300
+ return `default -src`.
4338
4301
4339
- 2. If |request|'s [= request/ initiator=] is "`prefetch `" or "`prerender`",
4340
- return `prefetch -src`.
4302
+ 2. If |request|'s <a for=" request"> initiator</a> is "`fetch `" or its
4303
+ <a for="request">destination</a> is "", return `connect -src`.
4341
4304
4342
4305
3. Switch on |request|'s <a for="request">destination</a> , and execute
4343
4306
the associated steps:
@@ -4460,10 +4423,6 @@ this algorithm returns normally if compilation is allowed, and throws a
4460
4423
::
4461
4424
1. Return `<< "manifest-src", "default-src" >> `.
4462
4425
4463
- : "`prefetch-src`"
4464
- ::
4465
- 1. Return `<< "prefetch-src", "default-src" >> `.
4466
-
4467
4426
: "`object-src`"
4468
4427
::
4469
4428
1. Return `<< "object-src", "default-src" >> `.
@@ -5015,8 +4974,45 @@ this algorithm returns normally if compilation is allowed, and throws a
5015
4974
</pre>
5016
4975
</div>
5017
4976
</section>
4977
+ <section>
4978
+ <h3 id="exfiltration">
4979
+ Exfiltration
4980
+ </h3>
4981
+
4982
+ Data exfiltration can occur when the contents of the request, such as the URL, contain
4983
+ information about the user or page that should be restricted and not shared.
4984
+
4985
+ Content Security Policy can mitigate data exfiltration if used to create allowlists of servers
4986
+ with which a page is allowed to communicate. Note that a policy which lacks the <a>default-src</a>
4987
+ directive cannot mitigate exfiltration, as there are kinds of requests that are not addressable
4988
+ through a more-specific directive ([^link/rel/prefetch^] , for example).
4989
+
4990
+ <div class="example">
4991
+ In the following example, a policy with draconian restrictions on images, fonts, and scripts
4992
+ can still allow data exfiltration via other request types (`fetch()`, [^link/rel/prefetch^] , etc):
4993
+
4994
+ <pre>
4995
+ <a http-header>Content-Security-Policy</a> : img-src 'none' script-src 'none' font-src 'none'
4996
+ </pre>
4997
+
4998
+ Supplementing this policy with `default-src 'none' ` would improve the page's robustness
4999
+ against this kind of attack.
5000
+ </div>
5001
+
5002
+ <div class="example">
5003
+ In the following example, the <a>default-src</a> directive appears to protect from
5004
+ exfiltration, however the <a>img-src</a> directive relaxes this restriction by using a
5005
+ wildcard, which allows data exfiltration to arbitrary endpoints. A policy's exfiltration
5006
+ mitigation ability depends upon the least-restrictive directive allowlist:
5007
+
5008
+ <pre>
5009
+ <a http-header>Content-Security-Policy</a> : default-src 'none' ; img-src *
5010
+ </pre>
5011
+ </div>
5018
5012
</section>
5019
5013
5014
+
5015
+
5020
5016
<section>
5021
5017
<h2 id="implementation-considerations">Implementation Considerations</h2>
5022
5018
0 commit comments