-
Notifications
You must be signed in to change notification settings - Fork 83
Use "least restrictive" directive instead of prefetch-src
#582
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Changes from 2 commits
04c1f65
8325f78
b4e05e6
e67c50b
4ca1217
c93a498
707f991
f9f3047
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -2140,6 +2140,14 @@ this algorithm returns normally if compilation is allowed, and throws a | |
out in more detail in the [[#should-block-request]] and | ||
[[#should-block-response]] algorithms. | ||
|
||
<div class="note"> | ||
In the case of resource hint such as [^link/rel/prefetch^] and [^link/rel/dns-prefetch^], | ||
<a>default-src</a> can be used as a way to restrict fetching the resource, as a means to prevent | ||
exfiltration. Resource hints don't have their own [=directive=] and they rely on | ||
<a>default-src</a> and follow the least-restrictive [=directive=]. | ||
</div> | ||
|
||
|
||
<div class="example"> | ||
The following header: | ||
|
||
|
@@ -2156,7 +2164,6 @@ this algorithm returns normally if compilation is allowed, and throws a | |
<a>img-src</a> <a grammar>'self'</a>; | ||
<a>manifest-src</a> <a grammar>'self'</a>; | ||
<a>media-src</a> <a grammar>'self'</a>; | ||
<a>prefetch-src</a> <a grammar>'self'</a>; | ||
<a>object-src</a> <a grammar>'self'</a>; | ||
<a>script-src-elem</a> <a grammar>'self'</a>; | ||
<a>script-src-attr</a> <a grammar>'self'</a>; | ||
|
@@ -2186,7 +2193,6 @@ this algorithm returns normally if compilation is allowed, and throws a | |
<a>img-src</a> <a grammar>'self'</a>; | ||
<a>manifest-src</a> <a grammar>'self'</a>; | ||
<a>media-src</a> <a grammar>'self'</a>; | ||
<a>prefetch-src</a> <a grammar>'self'</a>; | ||
<a>object-src</a> <a grammar>'self'</a>; | ||
<a>script-src-elem</a> https://example.com; | ||
<a>script-src-attr</a> <a grammar>'self'</a>; | ||
|
@@ -2703,74 +2709,6 @@ this algorithm returns normally if compilation is allowed, and throws a | |
|
||
4. Return "`Allowed`". | ||
|
||
<h4 id="directive-prefetch-src">`prefetch-src`</h4> | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. I think you'll also need to modify https://w3c.github.io/webappsec-csp/#effective-directive-for-a-request and https://w3c.github.io/webappsec-csp/#directive-fallback-list. There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Done |
||
|
||
The <dfn export>prefetch-src</dfn> directive restricts the URLs from which resources may be | ||
prefetched or prerendered. The syntax for the directive's name and value is described by the | ||
following ABNF: | ||
|
||
<pre> | ||
directive-name = "prefetch-src" | ||
directive-value = <a grammar>serialized-source-list</a> | ||
</pre> | ||
|
||
<div class="example"> | ||
Given a page with the following Content Security Policy: | ||
|
||
<pre> | ||
<a http-header>Content-Security-Policy</a>: <a>prefetch-src</a> https://example.com/ | ||
</pre> | ||
|
||
Fetches for the following code will return network errors, as the URLs provided do not match | ||
`prefetch-src`'s <a>source list</a>: | ||
|
||
<pre highlight="html"> | ||
<link rel="prefetch" src="https://example.org/"></link> | ||
<link rel="prerender" src="https://example.org/"></link> | ||
</pre> | ||
</div> | ||
|
||
<h5 algorithm id="prefetch-src-pre-request"> | ||
`prefetch-src` Pre-request check | ||
</h5> | ||
|
||
This directive's <a for="directive">pre-request check</a> is as follows: | ||
|
||
Given a <a for="/">request</a> (|request|) and a <a for="/">policy</a> (|policy|): | ||
|
||
1. Let |name| be the result of executing [[#effective-directive-for-a-request]] | ||
on |request|. | ||
|
||
2. If the result of executing [[#should-directive-execute]] on |name|, | ||
`prefetch-src` and |policy| is "`No`", return "`Allowed`". | ||
|
||
3. If the result of executing [[#match-request-to-source-list]] on |request|, | ||
this directive's [=directive/value=], and |policy|, | ||
is "`Does Not Match`", return "`Blocked`". | ||
|
||
4. Return "`Allowed`". | ||
|
||
<h5 algorithm id="prefetch-src-post-request"> | ||
`prefetch-src` Post-request check | ||
</h5> | ||
|
||
This directive's <a for="directive">post-request check</a> is as follows: | ||
|
||
Given a <a for="/">request</a> (|request|), a <a>response</a> (|response|), and a | ||
<a for="/">policy</a> (|policy|): | ||
|
||
1. Let |name| be the result of executing [[#effective-directive-for-a-request]] | ||
on |request|. | ||
|
||
2. If the result of executing [[#should-directive-execute]] on |name|, | ||
`prefetch-src` and |policy| is "`No`", return "`Allowed`". | ||
|
||
3. If the result of executing [[#match-response-to-source-list]] on |response|, | ||
|request|, this directive's [=directive/value=], and |policy|, | ||
is "`Does Not Match`", return "`Blocked`". | ||
|
||
4. Return "`Allowed`". | ||
|
||
<h4 id="directive-script-src">`script-src`</h4> | ||
|
||
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 | |
algorithm returns the violated <a>directive</a> if the request violates the | ||
policy, and "`Does Not Violate`" otherwise. | ||
|
||
1. Let |violates| be "`Does Not Violate`". | ||
1. If |request|'s [=request/initiator=] is "`prefetch`", then return the result of executing | ||
[[#does-resource-hint-violate-policy]] on |request| and |policy|. | ||
|
||
2. <a for=set>For each</a> |directive| of |policy|: | ||
2. Let |violates| be "`Does Not Violate`". | ||
|
||
3. <a for=set>For each</a> |directive| of |policy|: | ||
|
||
1. Let |result| be the result of executing |directive|'s | ||
<a for="directive">pre-request check</a> on |request| and |policy|. | ||
|
||
2. If |result| is "`Blocked`", then let |violates| be |directive|. | ||
|
||
3. Return |violates|. | ||
4. Return |violates|. | ||
|
||
<h5 id="does-resource-hint-violate-policy"> | ||
Does resource hint |request| violate |policy|? | ||
</h5> | ||
|
||
Given a <a for="/">request</a> (|request|) and a <a for="/">policy</a> (|policy|), this | ||
algorithm returns the default <a>directive</a> if the resource-hint request violates all the | ||
policies, and "`Does Not Violate`" otherwise. | ||
|
||
1. Let |defaultDirective| be |policy|'s first [=directive=] whose [=directive/name=] is | ||
"`default-src`". | ||
|
||
2. If |defaultDirective| does not exist, return "`Does Not Violate`". | ||
noamr marked this conversation as resolved.
Show resolved
Hide resolved
|
||
|
||
3. <a for=set>For each</a> |directive| of |policy|: | ||
|
||
1. Let |result| be the result of executing |directive|'s | ||
<a for="directive">pre-request check</a> on |request| and |policy|. | ||
|
||
2. If |result| is "`Allowed`", then return "`Does Not Violate`". | ||
|
||
4. Return "`Blocked`". | ||
|
||
<h5 id="match-nonce-to-source-list" algorithm> | ||
Does |nonce| match |source list|? | ||
|
@@ -4333,11 +4296,11 @@ this algorithm returns normally if compilation is allowed, and throws a | |
`null` or the <a for="directive">name</a> of the request's | ||
<dfn for="request" export>effective directive</dfn>: | ||
|
||
1. If |request|'s <a for="request">initiator</a> is "`fetch`" or its | ||
<a for="request">destination</a> is "", return `connect-src`. | ||
1. If |request|'s [=request/initiator=] is "`prefetch`" or "`prerender`", | ||
return `default-src`. | ||
|
||
2. If |request|'s [=request/initiator=] is "`prefetch`" or "`prerender`", | ||
return `prefetch-src`. | ||
2. If |request|'s <a for="request">initiator</a> is "`fetch`" or its | ||
<a for="request">destination</a> is "", return `connect-src`. | ||
|
||
3. Switch on |request|'s <a for="request">destination</a>, and execute | ||
the associated steps: | ||
|
@@ -4460,10 +4423,6 @@ this algorithm returns normally if compilation is allowed, and throws a | |
:: | ||
1. Return `<< "manifest-src", "default-src" >>`. | ||
|
||
: "`prefetch-src`" | ||
:: | ||
1. Return `<< "prefetch-src", "default-src" >>`. | ||
|
||
: "`object-src`" | ||
:: | ||
1. Return `<< "object-src", "default-src" >>`. | ||
|
@@ -5015,8 +4974,40 @@ this algorithm returns normally if compilation is allowed, and throws a | |
</pre> | ||
</div> | ||
</section> | ||
<section> | ||
<h3 id="exfiltration"> | ||
Exfiltration | ||
</h3> | ||
|
||
Data exfiltration can occur when the contents of the request, such as the URL, contain | ||
information about the user or page that should be restricted and not shared. | ||
|
||
To prevent exfiltration with CSP, it is important to set the <a>default-src</a> directive, to | ||
avoid a situation where a specific directive is omitted, and to ensure that other directives | ||
don't relax that restriction in a way that can allow exfiltration. | ||
noamr marked this conversation as resolved.
Show resolved
Hide resolved
|
||
|
||
<div class="example"> | ||
In the following example, a page that has only images, fonts and scripts, can still | ||
exfiltrate, e.g. by a [^link/rel/prefetch^]. Add <pre>default-src 'none'</pre> to avoid it. | ||
noamr marked this conversation as resolved.
Show resolved
Hide resolved
|
||
|
||
<pre> | ||
<a http-header>Content-Security-Policy</a>: img-src 'none' script-src 'none' font-src 'none' | ||
</pre> | ||
</div> | ||
noamr marked this conversation as resolved.
Show resolved
Hide resolved
|
||
|
||
<div class="example"> | ||
In the following example, the <a>default-src</a> directive appears to protect from | ||
exfiltration, however the <a>img-src</a> directive relaxes it, which allows data to exfiltrate | ||
either via an image or via resource hint. | ||
noamr marked this conversation as resolved.
Show resolved
Hide resolved
|
||
|
||
<pre> | ||
<a http-header>Content-Security-Policy</a>: default-src 'none' img-src *; | ||
noamr marked this conversation as resolved.
Show resolved
Hide resolved
|
||
</pre> | ||
</div> | ||
</section> | ||
|
||
|
||
|
||
<section> | ||
<h2 id="implementation-considerations">Implementation Considerations</h2> | ||
|
||
|
Uh oh!
There was an error while loading. Please reload this page.