Subresource Integrity Is Finally Mainstream... Almost
Subresource Integrity (SRI) has finally made its way into the Firefox release pipeline, having already seen release in Chromium/Chrome (currently version 45) and Opera (version 32).
Firefox Developer Edition (the “aurora” channel, currently v43) already includes SRI so the stable branch should see SRI land mid-December, based on the release schedule.
Here’s the CliffsNotes as a refresher on what SRI looks like:
<script src="https://example.com/my/script.js"
integrity="ALGO-BASE64HASH"
crossorigin="anonymous"
/>
Where ALGO
will be an acceptable hashing algorithm - SHA256
, SHA384
, or SHA512
(and perhaps others, which would be implementation dependent) and BASE64HASH
is the binary digest of the file contents encoded with Base64. How do you get a Base64 encoded binary digest? The W3C working draft on Subresource Integrity recommends using openssl directly:
echo -n "alert('Hello, world.');" | openssl dgst -sha384 -binary | openssl enc -base64 -A
in the real world (where you’re not echo
ing trivialized code) you could use cat
. In addition to that, I’m biased towards longer, slower hashes, so I prefer SHA512.
A passing example
If you check the source of this article, you’ll see a <script>
tag directly following this paragraph. It references /assets/examples/integrity-test-pass.js
with a correct SHA512 hash in the integrity
attribute. If you check your debug console (F12
in at least Firefox and Chromium) you should see your browser has loaded this file as usual. The contents of /assets/examples/integrity-test-pass.js
is a noop:
(function(){
// a test case for valid SRI
})();
The SHA512 hash of the file is qjMqRT1reFX0klfqaBYdVPOR2rg/6+Odk9LQojGKMWD1Sn3TIfnqZ2/z52o04ue6RavKXNLticjX1ZLrHOyGPw==
.
A failing example
Directly following this paragraph, you’ll find another <script>
tag, this time referencing /assets/examples/integrity-test-fail.js
with an incorrect SHA512 integrity
value. If you check your debug console, you SHOULD see an error regarding the failed verification, and the script SHOULD NOT have executed. If it did execute, you will see a notice (created by that script) at the bottom of this article.
window.onload = function() {
$("<div>")
.prop("id", "sri-failure")
.addClass("sri-test jumbotron")
.append($("<h1>")
.append("If you are reading this, your browser does not yet support Subresource Integrity.")
.append("<hr/>")
.append("Check back here the next time your browser updates to see if it's been enabled.")
)
.appendTo("#sri-warning");
};
The correct SHA512 digest of that file is wAavEEuwLqE67bOw3hY13q85nLMuOWuAaTUNIxSUsPPN15VzbdpuOlJ98hMfLrd9KAqBR4+9GQJHOdHhpmeZNQ==
but I have it entered in the integrity
attribute incorrectly as wlHqLoqGTkupQHAygefwRS03a4tyiPKs0KLHRmVikp/I5qCyCn16Fmd/JJd7MeCCIHRwQrOloY335+qW2Cy8ug==
(which I got by curl
ing the Google homepage). Just for the sake of it, I’ve also included a CSS file (with correct SRI information) to style the warning and make it as obnoxious as possible.