Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

What is the best SRI hash size?

I recently discovered the following nifty little site for generating SubResource Integrity (SRI) Tags for externally loaded resources. For example, enterring the latest jQuery URL (https://code.jquery.com/jquery-3.3.1.min.js), one gets the following <script> tag:

<script src="https://code.jquery.com/jquery-3.3.1.min.js" integrity="sha256-FgpCb/KJQlLNfOu91ta32o/NMZxltwRo8QtmkMRdAu8= sha384-tsQFqpEReu7ZLhBV2VZlAu7zcOV+rXbYlF2cqB8txI/8aZajjp4Bqd+V6D5IgvKT sha512-+NqPlbbtM1QqiK8ZAo4Yrj2c4lNQoGv8P79DPtKzj++l5jnN39rHA/xsqn8zE9l0uSoxaCdrOgFs6yjyfbBxSg==" crossorigin="anonymous"></script>

I understand the purpose of SRI hashes, and I know that they can use different hash sizes (256-, 384-, or 512-bit), but I had never seen all three used at once like this before. Digging into the MDN docs, I found that

An integrity value may contain multiple hashes separated by whitespace. A resource will be loaded if it matches one of those hashes.

But how exactly is that matching performed? Time for multiple questions in one SO post...

  1. Do browsers attempt to match the longest hash first, since its more secure, or the shortest first, since its faster?
  2. Would one really ever expect for one hash to match and not all three (other than the trivial case of a developer mistyping a hash)?
  3. Is there any benefit to providing all three hashes instead of just one?
  4. Similar to #1, If you only provide one hash value, which should you use? I typically see sites (e.g., Bootstrap) providing sha384-values in their example code. Is that because its right in the middle, not too big, not too small?
  5. Out of curiosity, can the integrity attribute be used on any tags beside <script> and <link>. I'm particularly wondering about multimedia tags like <img>, <source>, etc.
like image 842
Rabadash8820 Avatar asked Aug 30 '18 16:08

Rabadash8820


Video Answer


1 Answers

  1. Do browsers attempt to match the longest hash first, since its more secure, or the shortest first, since its faster?

Per https://w3c.github.io/webappsec-subresource-integrity/#agility, “the user agent will choose the strongest hash function in the list”.

  1. Would one really ever expect for one hash to match and not all three?

No. But as far as the browser behavior: If the strongest hash matches, the browser uses that and just ignores the rest (so it wouldn’t matter anyway whether the others match too or not).

  1. Is there any benefit to providing all three hashes instead of just one?

There is no current benefit in practice as far as I can see. That’s because per https://w3c.github.io/webappsec-subresource-integrity/#hash-functions, “Conformant user agents MUST support the SHA-256, SHA-384, and SHA-512 cryptographic hash functions”.

So currently, if you just specify a SHA-512 hash, all browsers that support SRI will use that.

But per https://w3c.github.io/webappsec-subresource-integrity/#agility the intent specifying multiple hashes is “to provide agility in the face of future cryptographic discoveries… Authors are encouraged to begin migrating to stronger hash functions as they become available”.

In other words, at some point in the future, browsers will start to add support for stronger hash functions (SHA-3-based ones https://en.wikipedia.org/wiki/SHA-3 or whatever).

Thus, since you’ll need to continue to target older browsers as well as newer ones, there will be a period of time when you’re targeting some browsers for which SHA-512 is the strongest hash function while also targeting the new browsers that have come along by that time which will have added support for some SHA-3 (or whatever) hash functions.

So in that case, you would need to specify multiple hashes in the integrity value.

  1. Similar to #1, If you only provide one hash value, which should you use?

A SHA-512 value.

I typically see sites (e.g., Bootstrap) providing sha384-values in their example code. Is that because its right in the middle, not too big, not too small?

I don't know why they choose to do it that way. But since browsers are required to support SHA-512 hashes, you don’t gain anything by specifying a SHA-384 hash instead — in fact you just lose the value of having the strongest hash function available.

  1. Out of curiosity, can the integrity attribute be used on any tags beside <script> and <link>.

No, it can’t be — not yet.

I'm particularly wondering about multimedia tags like <img>, <source>, etc.

As https://w3c.github.io/webappsec-subresource-integrity/#verification-of-html-document-subresources explains, the plan has always been for SRI to eventually be used for those too —

Note: A future revision of this specification is likely to include integrity support for all possible subresources, i.e., a, audio, embed, iframe, img, link, object, script, source, track, and video elements.

…but we are not yet in that future.

like image 73
sideshowbarker Avatar answered Nov 10 '22 21:11

sideshowbarker