I am currently exploring the Subresource Integrity security feature and I found out an implementation that disturbs me a bit. Basically, when you specify in a script that you want to check the integrity : it comes like this :
<script src="https://script.js"
integrity="sha384-correct_hash"
crossorigin="anonymous">
Then, if the hash matches, the script is executed. If it doesn't, the script is blocked.
After this, I tried to trigger another error by suppressing the algorithm. I expected another error of the same kind, but I found out something else : the resource is not blocked. I understand this attribute is needed according to the specification, but I wanted to observe the implementation of this error.
My question is why is the script/stylesheet not blocked when you specify "integrity" without a formal algorithm (sha256/sha384/sha512) ? As an example :
<!DOCTYPE html>
<html lang="en-US">
<head>
<meta charset="utf-8">
<meta name="viewport" content="width=device-width">
<title>Page</title>
</head>
<h2> My Test Page </h2>
<p>text for test(F12-->Console).</p>
<link rel="stylesheet"
href="https://cdn.jsdelivr.net/npm/[email protected]/dist/css/bootstrap.min.css"
integrity="sha384-Gn5384xqQ1aoWXA+058RXPxPg6fy4IWvTNh0E263XmFcJlSAwiGgFAW/dAiS6JXm"
crossorigin="anonymous">
<script src="https://code.jquery.com/jquery-3.2.1.slim.min.js"
integrity="sha384-KJ3o2DKtIkvYIK3UENzmM7KCkRr/rE9/Qpg6aAZGJwFDMVNA/GpGFF93hXpG5KkN"
crossorigin="anonymous">
</script>
<script>
$("p").hide()
</script>
The hash is the correct one, the stylesheet is applied and <p> elements are hidden using jquery.
If I modify the hash, the resources will be blocked.
But if I suppress the algo (shaXXX), whatever the hash I write, the ressource will be loaded and executed. The browser just sends an error in the browser (chrome 110) :Error parsing 'integrity' attribute ('XXXXXXXXXXXXXXXXXXXX'). The hash algorithm must be one of 'sha256', 'sha384', or 'sha512', followed by a '-' character. And with firefox(109) a warning.
ex :
<link rel="stylesheet"
href="https://cdn.jsdelivr.net/npm/[email protected]/dist/css/bootstrap.min.css"
integrity="not_a_good_hash"
crossorigin="anonymous">
<script src="https://code.jquery.com/jquery-3.2.1.slim.min.js"
integrity="Also_Not_A_GOOD_HASH"
crossorigin="anonymous"></script>
My view is : if a programmer specifies the integrity attribute, everything but the correct hash with the correct algo is supposed to be blocked. Can someone explain me this choice implementation, what are the reasons behind it ?