Generate Subresource Integrity hashes to verify external resources.
Subresource Integrity (SRI) is a security feature that enables browsers to verify that resources fetched from external sources (like CDNs) have not been tampered with. It works by comparing a cryptographic hash of the fetched resource against a hash you provide in your HTML.
If an attacker compromises a CDN or performs a man-in-the-middle attack, SRI prevents your users from executing malicious code because the hash won't match. This is a critical defense-in-depth measure for any website using third-party resources.
integrity attributecrossorigin="anonymous"<script src="https://cdn.example.com/library.min.js"
integrity="sha384-oqVuAfXRKap7fdgcCY5uykM6+R9GqQ8K/uxy9rx7HNQlGYl1kPzQho1wx4JwY8wC"
crossorigin="anonymous"></script>
<link rel="stylesheet"
href="https://cdn.example.com/styles.min.css"
integrity="sha384-MCw98/SFnGE8fJT3GXwEOngsV7Zt27NXFoaoApmYm81iuXoPkFOJwJ8ERdknLPMO"
crossorigin="anonymous">
While all three algorithms (SHA-256, SHA-384, SHA-512) are secure, SHA-384 is recommended for several reasons:
For SRI to work with cross-origin resources, the server must allow CORS (Cross-Origin Resource Sharing). You must also include the crossorigin attribute in your HTML:
| Value | Meaning |
|---|---|
crossorigin="anonymous" |
No credentials sent (most common) |
crossorigin="use-credentials" |
Sends cookies with the request |
SRI has prevented several potential supply chain attacks:
You can specify multiple hashes for a single resource, useful during version transitions:
<script src="https://cdn.example.com/lib.js"
integrity="sha384-oldHash sha384-newHash"
crossorigin="anonymous"></script>
The browser accepts the resource if any of the provided hashes match.
For production environments, integrate SRI hash generation into your build pipeline:
const SriPlugin = require('webpack-subresource-integrity');
module.exports = {
output: { crossOriginLoading: 'anonymous' },
plugins: [new SriPlugin({ hashFuncNames: ['sha384'] })]
};
cat file.js | openssl dgst -sha384 -binary | openssl base64 -A
const crypto = require('crypto');
const hash = crypto.createHash('sha384').update(fileContent).digest('base64');
console.log(`sha384-${hash}`);
Unsupported browsers ignore the integrity attribute and load resources normally.
Bootstrap 5:
sha384-EVSTQN3/azprG1Anm3QDgpJLIm9Nao0Yz1ztcQTwFspd3yD65VohhpuuCOmLASjC
jQuery 3.6:
sha384-vtXRMe3mGCbOeY7l30aIg8H9p3GdeSe4IFlP6G8JMa7o7lXvnz3GFKzPxzJdPfGK