Skip to content

Commit 04c1f65

Browse files
committed
Use "least restrictive" directive instead of prefetch-src
When prefetching a resource (or preconnecting to an origin), the destination of the request is unknown and also not important. e.g. if this resource is a script and would be disallowed by `script-src`, the directive would be invoked again when the response is about to be consumed and would be rejected then. The only security measure valid for prefetch/preconnect is to avoid exfiltration - i.e. block the request when the default directive blocks this URL and no other directive allows it. Closes w3c#542
1 parent 1f4904f commit 04c1f65

File tree

1 file changed

+28
-73
lines changed

1 file changed

+28
-73
lines changed

index.bs

+28-73
Original file line numberDiff line numberDiff line change
@@ -2156,7 +2156,6 @@ this algorithm returns normally if compilation is allowed, and throws a
21562156
<a>img-src</a> <a grammar>'self'</a>;
21572157
<a>manifest-src</a> <a grammar>'self'</a>;
21582158
<a>media-src</a> <a grammar>'self'</a>;
2159-
<a>prefetch-src</a> <a grammar>'self'</a>;
21602159
<a>object-src</a> <a grammar>'self'</a>;
21612160
<a>script-src-elem</a> <a grammar>'self'</a>;
21622161
<a>script-src-attr</a> <a grammar>'self'</a>;
@@ -2186,7 +2185,6 @@ this algorithm returns normally if compilation is allowed, and throws a
21862185
<a>img-src</a> <a grammar>'self'</a>;
21872186
<a>manifest-src</a> <a grammar>'self'</a>;
21882187
<a>media-src</a> <a grammar>'self'</a>;
2189-
<a>prefetch-src</a> <a grammar>'self'</a>;
21902188
<a>object-src</a> <a grammar>'self'</a>;
21912189
<a>script-src-elem</a> https://example.com;
21922190
<a>script-src-attr</a> <a grammar>'self'</a>;
@@ -2703,74 +2701,6 @@ this algorithm returns normally if compilation is allowed, and throws a
27032701

27042702
4. Return "`Allowed`".
27052703

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-
&lt;link rel="prefetch" src="https://example.org/"&gt;&lt;/link&gt;
2729-
&lt;link rel="prerender" src="https://example.org/"&gt;&lt;/link&gt;
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-
27742704
<h4 id="directive-script-src">`script-src`</h4>
27752705

27762706
The <dfn export>script-src</dfn> directive restricts the locations from which scripts
@@ -3794,16 +3724,41 @@ this algorithm returns normally if compilation is allowed, and throws a
37943724
algorithm returns the violated <a>directive</a> if the request violates the
37953725
policy, and "`Does Not Violate`" otherwise.
37963726

3797-
1. Let |violates| be "`Does Not Violate`".
3727+
1. If |request|'s [=request/initiator=] is "`prefetch`", then return the result of executing
3728+
[[#does-resource-hint-violate-policy]] on |request| and |policy|.
37983729

3799-
2. <a for=set>For each</a> |directive| of |policy|:
3730+
2. Let |violates| be "`Does Not Violate`".
3731+
3732+
3. <a for=set>For each</a> |directive| of |policy|:
38003733

38013734
1. Let |result| be the result of executing |directive|'s
38023735
<a for="directive">pre-request check</a> on |request| and |policy|.
38033736

38043737
2. If |result| is "`Blocked`", then let |violates| be |directive|.
38053738

3806-
3. Return |violates|.
3739+
4. Return |violates|.
3740+
3741+
<h5 id="does-resource-hint-violate-policy">
3742+
Does resource hint |request| violate |policy|?
3743+
</h5>
3744+
3745+
Given a <a for="/">request</a> (|request|) and a <a for="/">policy</a> (|policy|), this
3746+
algorithm returns the default <a>directive</a> if the resource-hint request violates all the
3747+
policies, and "`Does Not Violate`" otherwise.
3748+
3749+
1. Let |defaultDirective| be |policy|'s first [=directive=] whose [=directive/name=] is
3750+
"`default-src`".
3751+
3752+
2. If |defaultDirective| does not exist, return "`Does Not Violate`".
3753+
3754+
3. <a for=set>For each</a> |directive| of |policy|:
3755+
3756+
1. Let |result| be the result of executing |directive|'s
3757+
<a for="directive">pre-request check</a> on |request| and |policy|.
3758+
3759+
2. If |result| is "`Allowed`", then return "`Does Not Violate`".
3760+
3761+
4. Return "`Blocked`".
38073762

38083763
<h5 id="match-nonce-to-source-list" algorithm>
38093764
Does |nonce| match |source list|?

0 commit comments

Comments
 (0)