Closed Bug 1623953 Opened 1 year ago Closed 1 year ago

[rel=preload] Make SRI work with preload-as-speculative-load feature


(Core :: DOM: Security, enhancement, P1)




Tracking Status
firefox78 --- fixed


(Reporter: mayhemer, Assigned: mayhemer)


(Blocks 1 open bug)


(Whiteboard: [domsecurity-backlog1])


(4 files)

Part of Design documentation for rel=preload

If we hit:

<link rel="preload" as="script" href="script.js" />
<script src="script.js" integrity="sha-..." />

we won't perform the SRI check because the ScriptLoad request will know nothing about the integrity attribute from the <script> tag, we will just mostly jump over the <script> tag.

Same applies to <rel=stylesheet> for css.

This depends on bug 1618549 which will move the initial coalescing logic from the HTML5 parser to respective loaders what, BTW, allows examination of the <script> or <rel=stylesheet> tag's attributes and merging it with a running rel=preload, should there be.

This should be done as an additional "post-preload" SRI check, i.e. a second SRI verifier when a load is already in progress. Two reasons to that:

  1. we allow second check when the checksum method is different but both pass
  2. we will not race onload/onerror by setting the existing SRI checker lazily on an existing load. when sri from the tag fails, we still do onload for the link preload tag.

We must cache the preloaded data before we hit the actual tag and see (or not see) the integrity attribute to have the source for the hash calculation. This may be limiting or complicated...

Shouldn't this belong to DOM:Se

Type: defect → enhancement

(In reply to Mirko Brodesser (:mbrodesser) from comment #1)

Shouldn't this belong to DOM:Se

Good question. I'll see how Ethan thinks about this.

Flags: needinfo?(ettseng)

(In reply to Hsin-Yi Tsai [:hsinyi] from comment #2)

(In reply to Mirko Brodesser (:mbrodesser) from comment #1)

Shouldn't this belong to DOM:Se

Yeah, that makes sense. Let's move this bug over to DOM:Security. I know that link=preload currently lives behind the pref "network.preload-experimental". Before we move the switch to enable it for release we should make sure that SRI works correctly. Putting in the backlog in the meantime.

Component: DOM: Core & HTML → DOM: Security
Flags: needinfo?(ettseng)
Priority: -- → P3
Whiteboard: [domsecurity-backlog1]
No longer depends on: 1618549

After talking to guys from Google, with Emilio and spending some time figuring out the best approach to take for us, I came to this:

Speculative loading will be limited to only one request, using the current, HTML5 parser located de-duplication code, considering just a URL. Hence, during the prescan phase, only one speculative load started by the first tag (either <link preload> or consumer tag) will be existing, having SRI of that first tag, all other tags will be ignored during the prescan phase. Doing otherwise (like restart a speculative load with a different SRI) is a corner case optimization and beyond scope of the preload project as put.

Finding a speculative load for a regular <script> tag for reuse will check if the SRI of that consumer script is "not stronger" than SRI of the only one running or finished speculative load. If not, use the speculative load and remove it from preloads, otherwise, start a new load and remove the preload as well.

To find a speculative load for a <link stylesheet> tag we will simply add the SRI value in a smart way to the internal coalescing key (SheetLoadDataHashKey) so that preloads with "weaker" SRI will not be found to be reused/coalesced, new loads will be started during the DOM building phase (late).

For simplicity and because it would be another corner case, multiple link preloads with different SRI will all coalesce with the first <link preload> initiated load, likely the speculative one. We can file a followup to fire "error" event on those with "stronger" SRI.

  • Not stronger SRI means that the consumer tag's SRI is not more strict (more strong hash algo, same algo but different value, or simply present at all when not present on the speculative load). Examples:
speculative load SRI consumer load SRI use the speculative load
"" "" yes
"sha256-AAA" "" yes
"sha256-AAA" "md5-BBB" yes
"sha256-AAA" "sha256-AAA" yes
"" "sha256-AAA" no
"sha256-..." "sha384-..." no
"sha256-AAA" "sha256-BBB" no
Assignee: nobody → honzab.moz
Priority: P3 → P1
Blocks: 1636974
Pushed by
Provide comparative method on SRIMetadata to allow trust delegation to a stronger or identical SRI, r=emilio,ckerschb
Do an SRI check in ScriptLoader before reusing a speculative load initiated by <link preload>, r=dpalmeiro,hsivonen
Add SRI to CSS load hash-key to not use speculative link preloads with weaker SRI to satisfy consumer loads, r=emilio
Update web-platform tests to reflect the fixes, r=emilio
You need to log in before you can comment on or make changes to this bug.