What SRI protects against
A page that loads a script from a CDN trusts that CDN. If the CDN is compromised — or if a DNS poisoning, a TLS downgrade, or a malicious BGP route hijack succeeds — the attacker can serve a modified script and the page will execute it.
Subresource Integrity adds an integrity attribute carrying the
hash of the expected file. The browser computes the hash of what
it received; if it differs, the resource is rejected and the
script does not run. The crossorigin="anonymous" attribute is
required for cross-origin loads so the response is read into a
form the integrity check can hash.
<script src="https://cdn.example/lib-1.4.2.js"
integrity="sha384-Bg5IxjkYECdpEd0+Fz9kZD7+8n4gPRKt9YLVbXl5W+IOH7BtBgIQbyV3l/G6JUxz"
crossorigin="anonymous"></script>
<link rel="stylesheet"
href="https://cdn.example/lib-1.4.2.css"
integrity="sha384-z23gFw7w53JF1YIuJ06JQv4eFErXaYY9jBuGeoGiYZbE9p1qrjrUUaWDtxvUI3mt"
crossorigin="anonymous">
What integrity accepts
The attribute is a space-separated list of <algo>-<base64-hash>
tokens. The user agent picks the strongest algorithm it supports
and uses the corresponding hash.
Supported algorithms (per the SRI spec):
sha256— fastest, large attack surface against pre-image.sha384— recommended default.sha512— strongest in current SRI deployment; about 30% of observed integrity attributes use it (HTTP Archive 2024).
Including more than one algorithm is allowed and forward-
compatible: integrity="sha256-... sha384-...". The browser
picks the strongest it knows.
Generating the hash
openssl dgst -sha384 -binary lib-1.4.2.js | openssl base64 -A
Most build pipelines automate this. Vite, Webpack, Rollup, and
esbuild all have plugins (vite-plugin-sri, webpack-subresource-integrity)
that compute and inject the hash for every emitted asset.
About 8% of the top 10,000 sites on the Tranco list 2024 use SRI on at least one external resource — a small share but growing about 1.5 percentage points per year.
What SRI does not protect
- Same-origin resources are not the threat model. SRI is designed for third-party and CDN-hosted assets where the origin is outside the page’s trust boundary.
- Side-channel exfiltration — a script that runs successfully can still send data to an attacker. Combine SRI with Content Security Policy to constrain what a verified script can do.
- HTML and JSON resources. SRI applies only to
<script>and<link rel="stylesheet">(and<link rel="preload">of those types). HTML inclusion viafetch()is not SRI-checked by the browser; the application layer must verify. - Dynamic imports. ES module dynamic
import()statements ignore theintegrityattribute on the static<script>. Use the import maps integrity field for dynamic imports — the proposal reached cross-engine development in 2024.
What happens on mismatch
If the hash does not match, the user agent:
- Refuses to execute the script (or apply the stylesheet).
- Logs a console error.
- Fires the
errorevent on the element so JS can detect. - Treats the load as failed for purposes of network metrics.
The error message is engine-specific but always includes the expected and computed hashes. About 0.4% of SRI-protected loads fail at any given time per the HTTP Archive 2024 security report — mostly due to cache poisoning at intermediate proxies and content-encoding mismatches, not actual attacks.
Cross-engine support
SRI reached cross-engine support in 2018 across Chromium, WebKit, and Gecko. The WPT subset for SRI passes at about 99% in all three engines as of 2024.
caniuse for SRI reports about 96% global support.
Common pitfalls
crossoriginmissing on cross-origin resource. The integrity check does not run; the load proceeds without verification. The behaviour is silent unless you check the network panel.- Hash from a different version. Updating the upstream
library changes the hash. Pin the version in the URL
(
lib-1.4.2.js, notlib-latest.js) so the integrity match is stable. - CDN that adds compression headers. Some CDNs serve a re-compressed payload; the hash computed by your build no longer matches. Use a CDN that returns the same bytes you uploaded (or use SRI only on assets you control).
- Embedded
integrityin HTML at build time, dynamic asset resolution at runtime. A revved filename mismatch surfaces as an empty page; the script load fails silently. CI smoke tests catch this. - HTTP/2 server push. The pushed asset is checked against the integrity at the time of consumption, not push, so push preloads may sit idle if hashes change between push and consumption.
Further reading
- W3C Subresource Integrity.
- The SRI Hash Generator is the fastest way to compute a hash for an arbitrary public URL.
- Mozilla’s SRI for npm packages guide covers build-pipeline integration.
- Frederik Braun’s SRI design write-up remains the densest accessible explanation of the threat model.