What problem does SRI solve?
Anyone embedding JavaScript or CSS files from a third-party CDN trusts that CDN blindly: if the CDN gets hacked or starts serving manipulated code, that code runs automatically on every site that includes it — with all the privileges of the host site. The most prominent example: the Polyfill.io incident in 2024, when a popular CDN changed owners and suddenly injected malicious code into millions of websites.
SRI prevents this. When you embed the file, you also provide the hash of the expected content. The browser downloads the script, computes the hash and compares it — if the hash does not match, the script is not executed. CDN tampering becomes harmless.
How does SRI work?
You add the integrity attribute
to the <script> or
<link> tag, with an
algorithm and a Base64-encoded hash:
<script src="https://cdn.example.com/lib.js" integrity="sha384-oqVuAfXRKap7fdgcCY5uykM6+R9GqQ8K/uxy9rx7HNQlGYl1kPzQho1wx4JwY8wC" crossorigin="anonymous"></script>
Allowed algorithms are sha256,
sha384 and
sha512. Recommended: SHA-384.
You can also list multiple hashes (the browser accepts the script if any one matches)
— useful during a version transition.
Generating a hash
On the command line (Linux/Mac):
curl -s https://cdn.example.com/lib.js | openssl dgst -sha384 -binary | openssl base64 -A
Online:
srihash.org generates SRI hashes including a ready-made HTML snippet. Many CDNs (cdnjs.cloudflare.com, jsdelivr.net) display the matching integrity value next to the versioned URL.
crossorigin="anonymous"
For SRI to work, the external file must be served with proper CORS headers. The
crossorigin="anonymous"
attribute is mandatory; without it the browser will not perform the hash check. Good
CDNs serve the correct
Access-Control-Allow-Origin
header automatically — when your own file does not work, missing CORS is usually the
culprit.
When to use SRI
Always, whenever you embed third-party code:
- Libraries from cdnjs, jsDelivr, unpkg.
- Google Fonts CSS (the CSS, not the font files themselves — those are loaded separately).
- Analytics/tracking scripts (provided the vendor ships them with stable versions).
- Internal CDNs: even there, SRI is a useful second line of defense.
Not possible with scripts that are regenerated on every request
(Google Tag Manager, dynamic ad scripts) — the hash would change every time. There the
only mitigation is a strict Content-Security-Policy with script-src.
Common mistakes
- Forgetting to update the version: a new jQuery 3.7 build is pushed but the hash still points to the old one — the script no longer loads. Solution: pin to a specific version (jQuery 3.6.0, not "@latest") and update the hash whenever you bump it.
- Forgetting crossorigin: SRI does not kick in. Not all browsers warn you politely — some simply fail to load the file.
- Using only SHA-256: SHA-384 or SHA-512 are more secure and just as efficient.