16 July 2016
Subresource Integrity (SRI for short) is a technique that allows you to ensure that your assets are being served unaltered. For example:
This is something you have probably seen fairly commonly. CDN, or content delivery network, served assets improve page load times by distributing the content from locations physically closer to the end user. They also allow you to offload the bandwidth and resposibility for actually serving your assets.
But what happens when that third party is compromised? If all your site does is host cat gifs, it's probably not the end of the world. When you're dealing with sensitive information or accepting payments, however, a compromise could allow an attacker to steal valuable user information.
SRI allows us to add a cryptographically secure hash to our tags so that we can indicate what the actual signature of our sources should be. That way, if an attacker compromises a third party displaying assets on your page, they will not be able to serve you malicious code (or other assets, as we'll see below):
<script src="https://code.jquery.com/jquery-3.1.0.slim.min.js" integrity="sha384-uZ2OkdfFeYRaX81T8ZKlaMt5UJ7DkMwO8z95CYTpAtu9t6W7FaHvsa3xvalfNrnn"></script>
How Do I Generate That?
There are a few ways to generate the hash itself. The "hash" is actually the base64-encoded representation of the binary digest of the resource. You could put together a simple shell pipeline:
cat jquery-3.1.0.slim.min.js | openssl dgst -sha384 -binary | openssl enc -base64 -A
But typing this over and over gets old quick. There's also https://srihash.org, which will allow you to provide the URL of the resource and generate the hash for you.
There's also my favorite method (shameless plug incoming): https://github.com/f0rk/srihash. srihash provides a simple command line tool to generate subresource integrity hashes from local files or remote urls:
~$ srihash https://code.jquery.com/jquery-3.1.0.slim.min.js sha384-uZ2OkdfFeYRaX81T8ZKlaMt5UJ7DkMwO8z95CYTpAtu9t6W7FaHvsa3xvalfNrnn
What Supports SRI?
Two elements support SRI:
link. Simply include the hash of the resource
in the integrity attribute. If the script served varies
(for example, different users see different scripts) you
specify multiple whitespace separated hashes. If any hash
matches, the resource will load.
SRI is an experimental feature. At the moment, it is only supported by Chrome, Firefox, and Opera: http://caniuse.com/#feat=subresource-integrity.
SRI is one of many techniques to prevent the loading and execution of unexpected code. Other techniques, like content security policies, CORS and CORS attributes, and the meta referrer tag, should also be utilized as part of a scheme to make sure your data is protected.
You can also find this article here: https://truveris.github.io/articles/subresource-integrity/.