Skip to main content

What is Subresource Integrity?

SRI prevents compromised CDNs from delivering tainted JavaScript to your site — cryptographic integrity verification right in the browser.

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.

Check it yourself: HTTP-Header

HSTS, CSP, X-Frame-Options & Co. Enter a domain and see in seconds how your SUBRESOURCE-INTEGRITY is doing.

Also in the glossary