Subresource Integrity (SRI) adds an integrity attribute holding a hash of the file you expect. If a third-party host serves different bytes, the browser refuses to run the script or apply the stylesheet. You add it to external script and stylesheet tags, set crossorigin, and update the hash whenever you change versions.
What SRI protects against
Many sites load libraries from a CDN. If an attacker takes over that host, or tampers with a file on it, your page runs their code with full access to your users' sessions. SRI closes that route for files whose content you know in advance. MDN recommends it for scripts and stylesheets hosted by a third-party site.
It does not help with code you write, and it does nothing about a script that you load without a pinned version. It checks bytes, not intent.
The attribute format
The value is a space separated list of hashes. Each one is an algorithm name, a dash, then the base64 digest. The allowed algorithms are sha256, sha384 and sha512. If you list several, the browser uses only the strongest one. If you list several hashes of the same algorithm, any match is accepted, which lets you allow two versions of a file during a rollout.
SRI works on script elements and on link elements with rel set to stylesheet, preload or modulepreload.
<script src="https://cdn.example.com/lib.min.js"
integrity="sha384-REPLACE_WITH_REAL_DIGEST"
crossorigin="anonymous"></script>
Generating the hash
Never copy a hash from a blog post, including this one. Compute it from the exact file you intend to ship. With OpenSSL:
cat lib.min.js | openssl dgst -sha384 -binary | openssl base64 -A
Prefix the output with sha384-. Better still, download the file once, hash it, and confirm the digest against the project's published release if one exists. Hashing whatever the CDN returns today only proves that today's file matches itself.
The crossorigin requirement
A cross-origin request with an integrity attribute must use CORS. That means the CDN must send a suitable Access-Control-Allow-Origin header and your tag needs crossorigin. Without crossorigin the request goes out in no-cors mode, and MDN states that such a request with integrity will always fail. The reason is to stop attackers probing a resource by guessing hashes.
Keeping it maintained
The cost of SRI is upkeep. When a version changes, the hash must change in your code. Practical habits:
- Pin the file to an exact version in the URL, never a floating "latest".
- Generate the integrity value in your build step, not by hand.
- Add a test that loads each external tag and fails the build on a mismatch.
- Record each external file in your software bill of materials so it has an owner.
If a hash fails in production, treat it as a signal first. Either you changed the file or someone else did. Find out which before you update the hash.
Enforcing it and watching for gaps
MDN also describes an Integrity-Policy header that blocks scripts or styles lacking an integrity attribute, with a report-only twin. Start in report-only, fix the violations, then enforce. Some tags never will be pinnable, for example vendor snippets that change on the vendor's schedule. Those need a different control, such as moving them behind a tag review or a Content Security Policy.
Safeguard's dependency and SBOM scanning can list the third-party packages your builds pull in, and you can try a free scan at https://gold.safeguard.sh/scan. It does not replace an SRI check on tags that load from a browser.
Quick check
Does SRI work if the CDN does not send CORS headers?
No. The request must be made with CORS, so the host must allow your origin. Without that, the load fails when an integrity value is present.
Is a sha256 hash good enough?
The spec allows sha256, sha384 and sha512. Many teams pick sha384 as the usual default. Check your own policy before choosing.
Sources
Last reviewed: 19 October 2026.