Skip to content

Commit 8c2dcb5

Browse files
committed
Integrate with speculation rules
This upstreams the monkeypatches from https://wicg.github.io/nav-speculation/speculation-rules.html#content-security-policy. At a high level, the additions are: - A new directive, `inline-speculation-rules`, which can be used if developers want to block inline JavaScript `<script>`s but allow inline `<script type=speculationrules>`s. This is done by introducing a new script type, `script speculationrules`, to sit alongside the existing `script` and `script attribute` types; HTML passes this new value in. - Handling of the new `"speculationrules"` request destination, which is used by the `Speculation-Rules` HTTP header. It cannot be blocked by CSP.
1 parent 1137e96 commit 8c2dcb5

File tree

1 file changed

+30
-12
lines changed

1 file changed

+30
-12
lines changed

index.bs

Lines changed: 30 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -40,6 +40,7 @@ spec:html
4040
text: style
4141
type: element-attr
4242
text: ping
43+
text: type
4344
type:interface
4445
text:SharedWorker
4546
spec:fetch
@@ -696,7 +697,7 @@ spec:SRI; urlPrefix: https://w3c.github.io/webappsec-subresource-integrity
696697
/ "<dfn>'report-sample'</dfn>" / "<dfn>'unsafe-allow-redirects'</dfn>"
697698
/ "<dfn>'wasm-unsafe-eval'</dfn>" / "<dfn>'trusted-types-eval'</dfn>"
698699
/ "<dfn>'report-sha256'</dfn>" / "<dfn>'report-sha384'</dfn>"
699-
/ "<dfn>'report-sha512'</dfn>"
700+
/ "<dfn>'report-sha512'</dfn>" / "<dfn>'inline-speculation-rules'</dfn>"
700701

701702
ISSUE: Bikeshed `unsafe-allow-redirects`.
702703

@@ -1235,7 +1236,7 @@ spec:SRI; urlPrefix: https://w3c.github.io/webappsec-subresource-integrity
12351236
application, event handlers, etc.), and "`Blocked`" otherwise:
12361237

12371238
Note: The valid values for |type| are "`script`", "`script attribute`",
1238-
"`style`", and "`style attribute`".
1239+
"`script speculationrules`", "`style`", and "`style attribute`".
12391240

12401241
<ol class="algorithm">
12411242
1. Assert: |element| is not null.
@@ -2863,7 +2864,8 @@ Content-Type: application/reports+json
28632864
implicitly by not specifying a `script-src` (or `default-src`) directive,
28642865
or explicitly, by specifying "`unsafe-inline`", a
28652866
<a grammar>nonce-source</a> or a <a grammar>hash-source</a> that matches
2866-
the inline block.
2867+
the inline block, or specifying "`inline-speculation-rules`" when the
2868+
<{script/type}> attribute matches "`speculationrules`".
28672869

28682870
4. The following JavaScript execution sinks are gated on the "`unsafe-eval`" and "`trusted-types-eval`"
28692871
source expressions:
@@ -4006,7 +4008,7 @@ Content-Type: application/reports+json
40064008
Note: An empty source list (that is, a directive without a value: `script-src`,
40074009
as opposed to `script-src host1`) is equivalent to a source list containing `'none'`,
40084010
and will not match any URL.
4009-
4011+
40104012
Note: The `'none'` keyword has no effect when other source expressions are
40114013
present. That is, the list « `'none'` » does not match any URL. A list consisting
40124014
of « `'none'`, `https://example.com` », on the other hand, would match
@@ -4157,7 +4159,7 @@ Content-Type: application/reports+json
41574159
Note: The matching relation is asymmetric. That is, |pattern| matching |host| does not
41584160
mean that |host| will match |pattern|. For example, `*.example.com` <a>`host-part` matches</a>
41594161
`www.example.com`, but `www.example.com` does not <a>`host-part` match</a> `*.example.com`.
4160-
4162+
41614163
Note: A future version of this specification may allow literal IPv6 and IPv4 addresses,
41624164
depending on usage and demand. Given the weak security properties of IP addresses in
41634165
relation to named hosts, however, authors are encouraged to prefer the latter whenever possible.
@@ -4198,7 +4200,7 @@ Content-Type: application/reports+json
41984200

41994201
3. Let |normalizedInput| be null if |input| null; otherwise |input|
42004202
interpreted as decimal number.
4201-
4203+
42024204
4. If |normalizedInput| equals |url|'s [=url/port=], return "`Matches`".
42034205

42044206
5. If |url|'s [=url/port=] is null:
@@ -4330,7 +4332,12 @@ Content-Type: application/reports+json
43304332
Note: `'strict-dynamic'` only applies to scripts, not other resource
43314333
types. Usage is explained in more detail in [[#strict-dynamic-usage]].
43324334

4333-
3. If |expression| is an <a>ASCII case-insensitive</a> match for the
4335+
3. If |type| is "`script speculationrules`" and |expression| matches the
4336+
<a grammar>keyword-source</a>
4337+
"<a grammar>`'inline-speculation-rules'`</a>", set |allow all inline|
4338+
to `true`.
4339+
4340+
4. If |expression| is an <a>ASCII case-insensitive</a> match for the
43344341
<a grammar>`keyword-source`</a> "<a grammar>`'unsafe-inline'`</a>",
43354342
set |allow all inline| to `true`.
43364343

@@ -4381,8 +4388,9 @@ Content-Type: application/reports+json
43814388
1. If [[#allow-all-inline]] returns "`Allows`" given |list| and |type|,
43824389
return "`Matches`".
43834390

4384-
2. If |type| is "`script`" or "`style`", and [[#is-element-nonceable]]
4385-
returns "`Nonceable`" when executed upon |element|:
4391+
2. If |type| is "`script`", "`script speculationrules`", or "`style`", and
4392+
[[#is-element-nonceable]] returns "`Nonceable`" when executed upon
4393+
|element|:
43864394

43874395
1. <a for=set>For each</a> |expression| of |list|:
43884396

@@ -4403,8 +4411,8 @@ Content-Type: application/reports+json
44034411
"<a grammar>`'unsafe-hashes'`</a>",
44044412
set |unsafe-hashes flag| to `true`. Break out of the loop.
44054413

4406-
5. If |type| is "`script`" or "`style`", or |unsafe-hashes flag| is
4407-
`true`:
4414+
5. If |type| is "`script`", "`script speculationrules`", or "`style`", or
4415+
|unsafe-hashes flag| is `true`:
44084416

44094417
1. Set |source| to the result of executing <a>UTF-8 encode</a>
44104418
on the result of executing <a for="JavaScript string" data-lt="convert">JavaScript string converting</a>
@@ -4522,9 +4530,19 @@ Content-Type: application/reports+json
45224530
1. Return `connect-src`.
45234531

45244532
: "`report`"
4533+
: "`speculationrules`"
45254534
::
45264535
1. Return null.
45274536

4537+
<p class="note">At present, requests with the
4538+
"`speculationrules`" destination can only be issued by the
4539+
[:Speculation-Rules:] HTTP header, for which CSP does not apply.
4540+
If support is added for loading external speculation rules via
4541+
the <{script}> element's <{script/src}> attribute, for which CSP
4542+
would apply, then we would need to make this case more
4543+
complicated, for example by introducing a new
4544+
[=request/initiator=] and switching on that.
4545+
45284546
3. Return `connect-src`.
45294547

45304548
Note: The algorithm returns `connect-src` as a default fallback. This is
@@ -5179,7 +5197,7 @@ Content-Type: application/reports+json
51795197
<pre>
51805198
<a http-header>Content-Security-Policy</a>: img-src 'none'; script-src 'none'; font-src 'none'
51815199
</pre>
5182-
5200+
51835201
Supplementing this policy with `default-src 'none'` would improve the page's robustness
51845202
against this kind of attack.
51855203
</div>

0 commit comments

Comments
 (0)