What Is Subresource Integrity (SRI)
Subresource integrity, or SRI, is a security feature that allows your browser to distinguish if the files being retrieved have been maliciously altered. A site owner can implement various feature to help keep their website secure such as HSTS or TLS. However, these methods help keep the server secure, but not the content. A content security policy helps improve content security by defining which content sources are approved and can be loaded by the browser.
However, SRI differs from CSP in that it provides a cryptographic hash that the fetched file is required to match. This can be useful in the event that an attacker gains access to your web files delivered through a third party service (e.g. a CDN) and injects arbitrary content. Currently, subresource integrity's compatibility with browsers is currently set at about 75% when considering all major browsers.
How to use subresource integrity
The subresource integrity cryptographic hashes are included in a resource's <script>
or <link>
element as an integrity
attribute. The integrity value begins with a hash algorithm prefix (e.g. sha384
) followed by a dash and then the actual hash. Therefore, linking a CSS file with subresource integrity would resemble:
<link rel="stylesheet" href="https://example.keycdn.com/path/example.css" integrity="sha384-xnSV7Ujm6p40d9oLBjPsEZVraTaUO5LOWBOcat4SO3W8JI/jp7QXU5Be9/iy5bfE" crossorigin="anonymous">
Once a browser comes across a resource using SRI, it will handle it in the following manner:
- The browser downloads and compares the resource (script or style sheet) to the expected hash in the integrity value before executing it.
- If the resource matches the integrity value, the browser can execute it. Otherwise, the browser returns a network error and doesn't load said resource.
Using this method allows for your resources to remain inexecutable given they are unexpectedly changed. If an attacker makes any modification to a file, that file's hash will be significantly different from the original and therefore the browser's subresource integrity check will fail.
It should be noted as well that the third party service delivering your files must support CORS in order to work properly with SRI. The crossorigin="anonymous"
attribute and value in the above example enforces CORS and tells the browser to omit any cookies that the user may have associated with the domain.
Generating SRI hashes
Generating an SRI hash can be done in a couple of different ways. The first method involves using the command line to generate the hash which will look something like this (don't forget to replace FILENAME.js
with your filename):
openssl dgst -sha384 -binary FILENAME.js | openssl base64 -A
Alternatively, you can use a tool called srihash.org.
This tool allows you to simply copy the URL of the resource you intend to generate a hash for, and it returns the properly formatted <link>
or <script>
element for that resource. For example, let's say we wanted to generate a hash for a Font Awesome file, hosted on our server:
https://example.keycdn.com/path/example.css
We can simply enter this asset into the srihash tool and it will generate the following output:
<link rel="stylesheet" href="https://example.keycdn.com/path/example.css" integrity="sha384-MI32KR77SgI9QAPUs+6R7leEOwtop70UsjEtFEezfKnMjXWx15NENsZpfDgq8m8S" crossorigin="anonymous">
Using SRI with CSP
Within your content security policy, or CSP, you can define which types of files you want to have use subresource integrity. For example, if you want all style sheets to be validated using SRI, you can add the following rule to your CSP file:
Content-Security-Policy: require-sri-for style;
Additionally, if you want all JavaScript files to use SRI integrity you can use the following:
Content-Security-Policy: require-sri-for script;
You can also combine both script and style into one single rule such as:
Content-Security-Policy: require-sri-for script style;
Defining this makes it so that any style sheet or script asset without integrity will not be loaded.
Subresource integrity tool
Apart from the srihash tool mentioned in the section above, there are also some other available that can help you efficiently implement subresource integrity. The one we'll quickly discuss in this article is called webpack-subresource-integrity.
webpack is a popular module bundler which essentially generates static assets which represent modules with dependencies. The webpack Subresource Integrity plugin allows you to automatically add integrity to your asset files thus saving you time. The plugin itself has a fairly simple installation process:
npm install webpack-subresource-integrity --save-dev
Once installed, use the following webpack configuration example as defined on the plugin's page:
import SriPlugin from 'webpack-subresource-integrity';
const compiler = webpack({
output: {
crossOriginLoading: 'anonymous',
},
plugins: [
new SriPlugin({
hashFuncNames: ['sha256', 'sha384'],
enabled: process.env.NODE_ENV === 'production',
}),
],
});
Summary
SRI is a great way to help ensure your content is protected in the event that an attacker overtakes your web files and attempts to conduct malicious changes. If your browser is compatible in using subresource integrity, it will detect that the files and have altered and the hashes do not match up. Therefore, even though the attacker would be able to inject malicious code into a file, the website visitors won't be harmed as the file will simply not load, thus improving security and protection.
To learn more about subresource integrity, visit the W3 SRI specification.