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...
integrity
attribute be used on any tags beside <script>
and <link>
. I'm particularly wondering about multimedia tags like <img>
, <source>
, etc.
- 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”.
- 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).
- Is there any benefit to providing all three hashes instead of just one?
There is no current benefit in practice. 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 of 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.
- 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.
- 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
, andvideo
elements.
…but we are not yet in that future.