Web Security

What Is Subresource Integrity (SRI)?

A practical guide to Subresource Integrity: how the integrity attribute and a hash verify third-party scripts, generating hashes, and what its limits are.

StackOptic Research Team18 May 20268 min read
What Subresource Integrity (SRI) is and how to use it

Most modern websites load code they did not write and do not host — a JavaScript library from a CDN, an analytics snippet, a font or stylesheet from a third party. That convenience carries a risk: if the file on that external server is tampered with or swapped, your site will faithfully execute whatever it now contains, in your users' browsers, with your site's privileges. Subresource Integrity (SRI) is the browser feature that closes this gap: it lets you pin the exact expected contents of a third-party file with a cryptographic hash, so the browser refuses to run it if it has changed. This guide explains how SRI works, how to generate the hashes, what the browser does on a mismatch, the real limits, and how to check existing tags.

It is a focused look at one supply-chain defence within the broader how to protect your website from common attacks, and it pairs with what is a Content Security Policy and how to set one, which can require SRI for scripts and styles.

Answer first: the threat SRI addresses

When your page includes a script from, say, a public CDN, the browser fetches that file from the CDN's server and runs it. You are trusting two things: that the connection is secure (HTTPS handles that), and that the file on the CDN is the file you intended. That second assumption is where supply-chain risk lives. If an attacker compromises the CDN, the third-party provider, or the specific file — or if the wrong version is served — your page executes the altered code without complaint. Because third-party scripts run with the same access as your own, a tampered library can steal data, inject content, or hijack sessions.

HTTPS does not protect against this, because HTTPS only secures the file in transit; it says nothing about whether the file at the other end is genuine. SRI fills exactly that gap. You tell the browser the cryptographic hash of the file you expect; the browser fetches the file, hashes what it received, and only uses it if the hashes match. A tampered or swapped file produces a different hash, fails the check, and is blocked.

How SRI works

SRI is delivered as an integrity attribute on the <script> or <link> (stylesheet) tag, containing a base64-encoded cryptographic hash prefixed by its algorithm. It almost always appears alongside a crossorigin attribute. A real example for a CDN-hosted script looks like this:

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

When the browser loads this tag, it:

  1. Fetches the file from the src URL.
  2. Computes the hash of the received bytes using the algorithm named in integrity (here, SHA-384).
  3. Compares that computed hash with the value in the integrity attribute.
  4. Executes/applies the file only if they match. If they do not, the browser blocks the resource entirely.

The same applies to a stylesheet via <link rel="stylesheet" ... integrity="..." crossorigin="anonymous">. The Mozilla Developer Network (MDN) documents the feature and the exact attribute syntax authoritatively.

Why crossorigin is needed

You will notice crossorigin="anonymous" accompanying integrity on cross-origin resources, and it is not optional there. To hash a file's contents, the browser must be allowed to read those contents — and for a resource loaded from a different origin, reading the content requires CORS. Adding crossorigin="anonymous" tells the browser to fetch the file using CORS and without sending credentials (cookies), which lets it access the bytes to compute the hash. The server hosting the file must return appropriate CORS headers in response (reputable public CDNs do). Without crossorigin on a cross-origin file, the browser generally cannot enforce SRI. (For the mechanics of CORS itself, see what is CORS and how does it work?.)

Generating SRI hashes

An SRI hash is simply a supported digest of the exact file contents, base64-encoded, with the algorithm as a prefix (sha256-, sha384-, or sha512-). There are three easy ways to get one:

  • OpenSSL from a terminal. Hash the file and base64-encode it. For SHA-384, the canonical command is:
openssl dgst -sha384 -binary library.min.js | openssl base64 -A

Prefix the output with sha384- and that is your integrity value. (Swap in -sha256 or -sha512 for the other algorithms.)

  • CDN-published values. Many public CDNs display a ready-to-paste integrity value next to each hosted file, so you can copy the complete <script> tag with the hash already included. This is the easiest route when it is available.

  • Online SRI hash generators. Several web tools take a file or URL and return the full integrity attribute. Use a reputable one, and ideally verify the result, since you are trusting it to describe the file accurately.

Algorithmintegrity prefixNotes
SHA-256sha256-Supported; shortest digest
SHA-384sha384-Common default for the integrity attribute
SHA-512sha512-Longest digest

You can list multiple hashes in one integrity attribute (space-separated); the browser accepts the file if it matches any of them, and uses the strongest algorithm present. This is occasionally handy during transitions.

What the browser does on a mismatch

SRI is deliberately fail-closed. If the fetched file's computed hash does not match any value in integrity, the browser concludes the file is not what was expected and refuses to use it — a script is not executed, a stylesheet is not applied. There is no prompt and no silent fallback to running it anyway: a potentially compromised asset is simply blocked. The browser typically logs an error to the Console explaining the integrity failure, which is how you would notice and diagnose it.

This behaviour is the whole value proposition: a tampered or swapped CDN file is converted from running malicious code in every visitor's browser into a blocked resource and a console error. But it has a flip side you must plan for: if the legitimate file changes and you do not update the hash, SRI will block your own resource. That is not a bug — it is SRI doing exactly its job — but it dictates how you use it.

The limits of SRI

SRI is valuable but narrow, and being clear about its limits keeps you from misusing it:

  • It suits fixed, version-pinned files, not changing ones. Because any change to the file breaks the hash, SRI works best on specific, immutable versions (e.g. library@1.2.3) that you update deliberately. It is unsuitable for assets that legitimately change without warning — a "latest" URL that auto-updates, or a dynamically generated script — because every update would block the resource until you regenerate the hash.
  • It only covers what you reference directly. SRI protects the file in the tag. If that script then loads further scripts at runtime, those are not automatically covered by the parent's integrity check.
  • It does not replace HTTPS. HTTPS protects transit; SRI protects against the file being wrong even if transit is fine. You need both.
  • It does not replace a CSP. A Content Security Policy controls which sources may load at all and can even require SRI for scripts and styles (via the require-sri-for style of control). SRI verifies a specific file; CSP governs sources and policy. They are complementary layers.
  • It is not a silver bullet for third-party risk. It verifies integrity, not intent — a legitimately updated but newly malicious version, signed off via an updated hash, would still run. It also does nothing for non-static third-party risks. It is one strong layer among several.

The practical consequence: reach for SRI on third-party scripts and styles you load by fixed version from a CDN, and accept that you will update the hash when you deliberately update the version — which is good discipline anyway.

How to check existing tags for SRI

Auditing whether a site (yours or another's) uses SRI is quick:

1. View the page source / inspect the elements. Open DevTools → Elements (or view source) and look at the <script src="..."> and <link rel="stylesheet" ...> tags that point to external domains. If they carry an integrity="sha..." attribute (with crossorigin), SRI is in use for that resource; if not, that third-party asset is loaded without integrity verification.

2. The Console on failure. If an SRI check fails in practice, the Console prints an explicit integrity-mismatch error naming the resource — the fastest signal that a hash is wrong or a file has changed.

3. Header and policy context. Whether a site requires SRI is part of its broader security posture, visible alongside its CSP and other headers. For reading those, see how to read a website's HTTP headers. Broader audits, StackOptic included, report on the headers and third-party resources a site exposes, which helps you see where integrity verification is and is not present.

Putting it together with the other layers

SRI is most powerful as one part of a layered front-end security setup. HTTPS and HSTS secure the connection (see what is HSTS and how to enable it). A Content Security Policy restricts which origins can supply scripts and styles at all, and can mandate SRI for them. SRI then verifies that the specific approved files are exactly what you expect. And securing your cookies limits the damage if anything does slip through. No single one of these is sufficient alone; together they make tampering with your front-end substantially harder. That defence-in-depth philosophy — assume any one layer can fail, so stack several — runs through all of how to protect your website from common attacks.

A quick SRI checklist

  • Add integrity (with crossorigin="anonymous") to third-party <script> and <link> tags loaded from a CDN.
  • Use version-pinned file URLs so the contents are stable.
  • Generate the hash with OpenSSL, a CDN-published value, or a reputable generator (SHA-384 is a good default).
  • Remember to update the hash whenever you intentionally update the file version.
  • Confirm the CDN returns CORS headers so the integrity check can run.
  • Verify in DevTools that external tags carry integrity, and watch the Console for mismatch errors.
  • Combine SRI with HTTPS, HSTS and a CSP — it complements, never replaces, them.

Go deeper

Want to see which third-party resources and security headers your site exposes? Analyse any URL with StackOptic — security, performance and SEO in one free report.

Frequently asked questions

What is Subresource Integrity (SRI)?

Subresource Integrity (SRI) is a browser security feature that lets a page verify that a resource it loads from another server — typically a script or stylesheet from a CDN — has not been modified. You include a cryptographic hash of the expected file in the tag's integrity attribute. The browser fetches the file, hashes its contents, and only runs or applies it if the hash matches. If it does not, the file is blocked, protecting against tampered third-party assets.

How do I generate an SRI hash?

You hash the exact file contents with SHA-256, SHA-384 or SHA-512 and base64-encode the result, prefixed with the algorithm. From a terminal you can run an OpenSSL command that produces the digest and base64-encodes it. Many CDNs publish ready-made integrity values for their hosted files, and online SRI hash generators will produce the attribute for a given URL or file. SHA-384 is a common choice for the integrity attribute.

What happens if an SRI hash does not match?

If the fetched resource's computed hash does not equal any hash in the integrity attribute, the browser treats the file as compromised and refuses to use it — the script does not execute and the stylesheet is not applied. This is a deliberate fail-closed behaviour: a tampered or swapped file is blocked rather than run. It also means a legitimate update to the file will break unless you update the hash, so SRI suits version-pinned assets.

Why does SRI need the crossorigin attribute?

Resources loaded cross-origin must be fetched in a way that allows the browser to read their contents for hashing, which requires CORS. Adding crossorigin="anonymous" makes the browser request the file with CORS and without credentials, so it can compute the integrity hash. The server hosting the file must return appropriate CORS headers. Without crossorigin on a cross-origin resource, SRI generally cannot be enforced, which is why the two attributes usually appear together.

Does SRI replace HTTPS or a Content Security Policy?

No. SRI complements them but replaces neither. HTTPS protects a file in transit between server and browser, while SRI verifies the file is the exact one you expect even if the hosting server itself is compromised — a different threat. A Content Security Policy controls which sources may load at all and can even require SRI for scripts and styles. Use HTTPS, CSP and SRI together; each addresses a layer the others do not.

Analyse any website with StackOptic

Get the full technology stack, performance, security and SEO report in seconds — free.

Analyse a website

Related articles