@@ -705,6 +705,8 @@ spec:SRI; urlPrefix: https://w3c.github.io/webappsec-subresource-integrity
705
705
<dfn>base64-value</dfn> = 1*( <a>ALPHA</a> / <a>DIGIT</a> / "+" / "/" / "-" / "_" )*2( "=" )
706
706
707
707
; Digests: 'sha256-[digest goes here]'
708
+ <dfn>url-hash-source</dfn> = "'url-" <a>hash-algorithm</a> "-" <a>base64-value</a> "' "
709
+ <dfn>eval-hash-source</dfn> = "'eval-" <a>hash-algorithm</a> "-" <a>base64-value</a> "' "
708
710
<dfn>hash-source</dfn> = "'" <a>hash-algorithm</a> "-" <a>base64-value</a> "' "
709
711
<dfn>hash-algorithm</dfn> = "sha256" / "sha384" / "sha512"
710
712
</pre>
@@ -1546,8 +1548,13 @@ spec:SRI; urlPrefix: https://w3c.github.io/webappsec-subresource-integrity
1546
1548
[=ASCII case-insensitive=] match for the string "<a grammar>`'trusted-types-eval'`</a> ", then skip the
1547
1549
following steps.
1548
1550
1549
- 1. If |source-list| contains a [=source expression=] which is an [=ASCII case-insensitive=] match for the
1550
- string "<a grammar>`'unsafe-eval'`</a> ", then skip the following steps.
1551
+ 1. If the result of executing [[#match-eval-hash-to-source-list]] on |source-list| and |sourceString|
1552
+ is "`Matches`", then skip the following steps.
1553
+
1554
+ 1. If |source-list| does not contain a [=source expression=] that is a match for the
1555
+ "<a grammar>`'eval-hash-source'`</a> " grammar and |source-list| contains a [=source expression=] which is an
1556
+ [=ASCII case-insensitive=] match for the string "<a grammar>`'unsafe-eval'`</a> ", then skip the
1557
+ following steps.
1551
1558
1552
1559
1. Let |violation| be the result of executing [[#create-violation-for-global]] on
1553
1560
|global|, |policy|, and "`script-src`".
@@ -3771,7 +3778,11 @@ Content-Type: application/reports+json
3771
3778
for="request"> integrity metadata</a> and this directive's <a
3772
3779
for="directive"> value</a> is "`Matches`", return "`Allowed`".
3773
3780
3774
- 3. If |directive|'s <a for="directive">value</a> contains a <a>source
3781
+ 3. If the result of executing [[#match-url-hash-to-source-list]] on
3782
+ this directive's <a for="directive">value</a> and |request|'s
3783
+ <a for="request">current url</a> is "`Matches`", return "`Allowed`".
3784
+
3785
+ 4. If |directive|'s <a for="directive">value</a> contains a <a>source
3775
3786
expression</a> that is an <a>ASCII case-insensitive</a> match for
3776
3787
the "<a grammar>`'strict-dynamic'`</a> " <a grammar>keyword-source</a> :
3777
3788
@@ -3783,9 +3794,13 @@ Content-Type: application/reports+json
3783
3794
Note: "<a grammar>`'strict-dynamic'`</a> " is explained in more detail
3784
3795
in [[#strict-dynamic-usage]] .
3785
3796
3786
- 4. If the result of executing [[#match-request-to-source-list]] on
3787
- |request|, |directive|'s <a for="directive">value</a> , and |policy|,
3788
- is "`Does Not Match`", return "`Blocked`".
3797
+ 5. If |directive|'s <a for="directive">value</a> does not contain a
3798
+ <a>source expression</a> that is a match for the
3799
+ "<a grammar>`'url-hash-source'`</a> " grammar:
3800
+
3801
+ 1. If the result of executing [[#match-request-to-source-list]] on
3802
+ |request|, |directive|'s <a for="directive">value</a> , and
3803
+ |policy|, is "`Does Not Match`", return "`Blocked`".
3789
3804
3790
3805
2. Return "`Allowed`".
3791
3806
@@ -4404,53 +4419,104 @@ Content-Type: application/reports+json
4404
4419
set |unsafe-hashes flag| to `true`. Break out of the loop.
4405
4420
4406
4421
5. If |type| is "`script`" or "`style`", or |unsafe-hashes flag| is
4407
- `true`:
4422
+ `true`, return result of executing [[#match-value-hash-to-source-list]] on
4423
+ |source|, "`content`" and |list|.
4408
4424
4409
- 1. Set |source| to the result of executing <a>UTF-8 encode</a>
4410
- on the result of executing <a for="JavaScript string" data-lt="convert">JavaScript string converting</a>
4411
- on |source|.
4425
+ Note: Hashes apply to inline <{script}> and inline <{style}> . If the
4426
+ "<a grammar>`'unsafe-hashes'`</a> " source expression is present,
4427
+ they will also apply to event handlers, style attributes and `javascript:`
4428
+ navigations.
4412
4429
4413
- 2. <a for=set>For each</a> |expression| of |list|:
4430
+ ISSUE(w3c/webappsec-csp#426): This should handle ` 'strict-dynamic' ` for dynamically inserted inline scripts.
4414
4431
4415
- 1 . If |expression| matches the <a grammar>`hash-source`</a> grammar:
4432
+ 6 . Return "`Does Not Match`".
4416
4433
4417
- 1. Let |algorithm| be null.
4434
+ <h5 id="match-url-hash-to-source-list" algorithm>
4435
+ Does the hash of |url| match |source list|?
4436
+ </h5>
4418
4437
4419
- 2. If |expression|'s <a grammar>`hash-algorithm`</a> part is an
4420
- <a>ASCII case-insensitive</a> match for "sha256", set
4421
- |algorithm| to <a>SHA-256</a> .
4438
+ Given a <a>source list</a> |source list| and a url |url|, this algorithm
4439
+ returns "`Matches`" or "`Does Not Match`".
4422
4440
4423
- 3 . If |expression|'s <a grammar>`hash-algorithm`</a> part is an
4424
- <a>ASCII case-insensitive</a> match for "sha384", set
4425
- |algorithm| to <a>SHA-384</a> .
4441
+ 1 . Return the result of executing
4442
+ [[#match-value-hash-to-source-list]] on |url|'s {{URL/href}} ,
4443
+ "`url-hash`", and |source list| .
4426
4444
4427
- 4. If |expression|'s <a grammar>` hash-algorithm`</a> part is an
4428
- <a>ASCII case-insensitive</a> match for "sha512", set
4429
- |algorithm| to <a>SHA-512</a> .
4445
+ <h5 id="match-eval- hash-to-source-list" algorithm>
4446
+ Does the hash of |sourceString| match |source list|?
4447
+ </h5>
4430
4448
4431
- 5. If |algorithm| is not null:
4449
+ Given a <a>source list</a> |source list| and a source string |sourceString|,
4450
+ this algorithm returns "`Matches`" or "`Does Not Match`".
4432
4451
4433
- 1. Let |actual| be the result of <a>base64 encoding</a> the
4434
- result of applying |algorithm| to |source|.
4452
+ 1. Return the result of executing
4453
+ [[#match-value-hash-to-source-list]] on |sourceString|, "`eval-hash`",
4454
+ and |source list|.
4435
4455
4436
- 2. Let |expected| be |expression|'s <a grammar>`base64-value`</a> part,
4437
- with all '`-`' characters replaced with '`+`' , and all '`_`' characters
4438
- replaced with '`/`' .
4456
+ <h5 id="is-expression-of-hash-type" algorithm>
4457
+ Is |expression| of |hash type|?
4458
+ </h5>
4439
4459
4440
- Note: This replacement normalizes hashes expressed in [=base64url
4441
- encoding=] into [=base64 encoding=] for matching .
4460
+ Given a {{String}} |hash type| and a <a grammar>source-expression</a>
4461
+ |expression|, this algorithm returns "`Yes`" or "`No`" .
4442
4462
4443
- 3 . If |actual | is <a for="string" lt="is">identical to</a>
4444
- |expected| , return "`Matches `".
4463
+ 1 . If |hash type | is "url-hash" and |expression| matches the
4464
+ <a grammar>`url-hash-source`</a> grammar , return "`Yes `".
4445
4465
4446
- Note: Hashes apply to inline <{script}> and inline <{style}> . If the
4447
- "<a grammar>`'unsafe-hashes'`</a> " source expression is present,
4448
- they will also apply to event handlers, style attributes and `javascript:`
4449
- navigations.
4466
+ 2. If |hash type| is "eval-hash" and |expression| matches the
4467
+ <a grammar>`eval-hash-source`</a> grammar, return "`Yes`".
4450
4468
4451
- ISSUE(w3c/webappsec-csp#426): This should handle `'strict-dynamic' ` for dynamically inserted inline scripts.
4469
+ 3. If |expression| matches the <a grammar>`hash-source`</a> grammar,
4470
+ return "`Yes`".
4452
4471
4453
- 6. Return "`Does Not Match`".
4472
+ 4. Return "`No`".
4473
+
4474
+ <h5 id="match-value-hash-to-source-list" algorithm>
4475
+ Does the hash of |value| match |source list|?
4476
+ </h5>
4477
+
4478
+ Given a {{String}} |value|, {{String}} |hash type|, and a <a>source list</a>
4479
+ |source list| type , this algorithm returns "`Matches`" or "`Does Not Match`".
4480
+
4481
+ 1. Set |value| to the result of executing <a>UTF-8 encode</a>
4482
+ on the result of executing <a for="JavaScript string" data-lt="convert">JavaScript string converting</a>
4483
+ on |value|.
4484
+
4485
+ 2. <a for=set>For each</a> |expression| of |source list|:
4486
+
4487
+ 1. If the result of executing [[#is-expression-of-hash-type]] with
4488
+ |hash type| and |expression| is "`Yes`":
4489
+
4490
+ 1. Let |algorithm| be null.
4491
+
4492
+ 2. If |expression|'s <a grammar>`hash-algorithm`</a> part is an
4493
+ <a>ASCII case-insensitive</a> match for "sha256", set
4494
+ |algorithm| to <a>SHA-256</a> .
4495
+
4496
+ 3. If |expression|'s <a grammar>`hash-algorithm`</a> part is an
4497
+ <a>ASCII case-insensitive</a> match for "sha384", set
4498
+ |algorithm| to <a>SHA-384</a> .
4499
+
4500
+ 4. If |expression|'s <a grammar>`hash-algorithm`</a> part is an
4501
+ <a>ASCII case-insensitive</a> match for "sha512", set
4502
+ |algorithm| to <a>SHA-512</a> .
4503
+
4504
+ 5. If |algorithm| is not null:
4505
+
4506
+ 1. Let |actual| be the result of <a>base64 encoding</a> the
4507
+ result of applying |algorithm| to |value|.
4508
+
4509
+ 2. Let |expected| be |expression|'s <a grammar>`base64-value`</a> part,
4510
+ with all '`-`' characters replaced with '`+`' , and all '`_`' characters
4511
+ replaced with '`/`' .
4512
+
4513
+ Note: This replacement normalizes hashes expressed in [=base64url
4514
+ encoding=] into [=base64 encoding=] for matching.
4515
+
4516
+ 3. If |actual| is <a for="string" lt="is">identical to</a>
4517
+ |expected|, return "`Matches`".
4518
+
4519
+ 3. Return "`Does Not Match`".
4454
4520
4455
4521
<h3 id="directive-algorithms">Directive Algorithms</h3>
4456
4522
0 commit comments