Website Spec
Security Recommended Updated 2026-05-29

Subresource Integrity (SRI)

SRI adds a cryptographic hash to every third-party script and stylesheet so the browser refuses to run modified files. Essential for any external JS or CSS you depend on.

What it is

Subresource Integrity is a W3C standard that lets you pin the exact content of a script or stylesheet. You include a cryptographic hash of the file in the integrity attribute, and the browser refuses to execute the resource if the hash does not match.

<script
  src="https://cdn.example.com/widget.js"
  integrity="sha384-oqVuAfXRKap7fdgcCY5uykM6+R9GqQ8K/uxy9rx7HNQlGYl1kPzQho1wx4JwY8wC"
  crossorigin="anonymous"
></script>

SRI applies to <script> and <link rel="stylesheet">, and also <link rel="preload"> and <link rel="modulepreload">.

Why it matters

Every external script you load runs with full access to your origin. If the CDN is compromised, if an attacker buys an abandoned npm package, or if a CDN ops mistake swaps a file, that script can read cookies, exfiltrate form data, and rewrite the DOM. SRI shifts trust from “the CDN is currently honest” to “the file is byte-for-byte the one we audited”.

This is the standard defence against the kind of supply-chain attack that hit Magecart, Polyfill.io, and Event-Stream. CSP can restrict which hosts you trust; SRI restricts which specific files you trust on those hosts.

How to implement

For every external script or stylesheet, compute a SHA-384 hash of the exact file content and include it in the integrity attribute. Add crossorigin="anonymous" so the browser sends a CORS request and can verify the response without credentials.

<link
  rel="stylesheet"
  href="https://cdn.example.com/styles.css"
  integrity="sha384-EVSTQN3/azprG1Anm3QDgpJLIm9Nao0Yz1ztcQTwFspd3yD65VohhpuuCOmLASjC"
  crossorigin="anonymous"
>

Generate the hash on the command line:

curl -s https://cdn.example.com/widget.js | openssl dgst -sha384 -binary | openssl base64 -A

SRI supports sha256, sha384, and sha512. SHA-384 is the recommended default. You may list multiple hashes separated by spaces; the browser passes the resource if any one matches — useful for a graceful version rollover.

Pair SRI with a strict CSP. CSP says “only load scripts from these hosts”; SRI says “and only this exact file from that host”.

Common mistakes

  • Forgetting crossorigin="anonymous". Without it, the browser silently refuses to validate the integrity and the script is blocked.
  • Pinning to a “latest” CDN URL. The hash and the URL must match a specific immutable version. Use /[email protected]/widget.js, never /widget/widget.js.
  • Updating the script but not the hash. The page breaks. Automate hash generation in your build.
  • Using SRI on first-party assets you already control. It is harmless but not the highest-value place to spend the effort; reserve attention for third parties.

Verification

  • View source. Every <script src="https://…"> and external <link rel="stylesheet"> should have an integrity and crossorigin attribute.
  • Tamper with a byte of the file (via a local proxy) and confirm the browser refuses to run it; the console reports “Failed to find a valid digest”.
  • Use a tool like SRI Hash Generator to compute hashes for ad-hoc checks.
  • Audit dependency upgrades: any time a third-party file URL changes, the hash must change with it.

Related topics

Sources & further reading

Search
esc close navigate open