Every time a browser loads a script from a CDN, it trusts that the CDN is serving the correct, unmodified file. If the CDN is compromised, misconfigured, or serving stale content, the browser executes whatever it receives. No questions asked.
Subresource Integrity (SRI) changes this dynamic. It allows you to specify a cryptographic hash of the expected content. The browser fetches the resource, computes its hash, and refuses to execute it if the hash does not match. It is a simple, effective defense against one of the most impactful classes of supply chain attacks.
And almost nobody uses it.
The Problem SRI Solves
CDN Compromise
CDNs serve JavaScript libraries to millions of websites. A single compromised CDN endpoint can inject malicious code into every website that loads scripts from it. The Polyfill.io incident demonstrated this at scale: after the domain changed ownership, the new operators injected malicious redirects into the polyfill script served to hundreds of thousands of websites.
Without SRI, every website loading from the compromised CDN executed the malicious code. With SRI, the browser would have blocked the modified script because its hash would not match the expected value.
BGP Hijacking
An attacker who hijacks BGP routes to a CDN can intercept and modify traffic, serving malicious scripts instead of legitimate ones. Even with HTTPS, a sufficiently sophisticated attacker with control over a certificate authority or the ability to exploit certificate issuance processes can serve modified content.
SRI provides a defense-in-depth layer that does not depend on the TLS trust model. Even if the network transport is compromised, the content integrity check catches the modification.
Accidental Corruption
CDNs can serve corrupted or incorrect files due to configuration errors, caching bugs, or deployment failures. SRI prevents corrupted scripts from executing and affecting your users.
How SRI Works
Add an integrity attribute to your script or link tags:
<script
src="https://cdn.example.com/library.js"
integrity="sha384-oqVuAfXRKap7fdgcCY5uykM6+R9GqQ8K/uxy9rx7HNQlGYl1kPzQho1wx4JwY8wC"
crossorigin="anonymous"
></script>
The browser downloads the file, computes the SHA-384 hash, and compares it to the value in the integrity attribute. If they match, the script executes. If they do not match, the browser blocks it and reports an error.
The crossorigin attribute is required for SRI on cross-origin resources. Without it, the browser cannot read the resource content to compute the hash.
Why SRI Adoption Is Low
Dynamic Resources
SRI requires a known, static hash. If the CDN serves different content based on the user agent, geographic location, or other factors, the hash will not match for some users. This is not how reputable CDNs serve JavaScript libraries, but it is a concern that deters some teams.
Version Updates
When a library is updated, the hash changes. If you pin to a specific version (jquery@3.7.1), this is not a problem because the content at that version URL should never change. If you use a floating URL that serves the latest version, SRI breaks on every update.
The solution is to pin library versions explicitly and update the SRI hash when you update the library version. This is extra work but also forces you to deliberately manage your third-party dependencies, which is a security benefit.
Build Tooling Gaps
Many build tools do not automatically generate SRI hashes for external resources. Teams must add SRI manually or integrate SRI generation into their build pipeline, which adds friction.
Perceived Low Risk
Teams often underestimate the risk of CDN compromise. "It is a major CDN, they will not get hacked" is a common justification. The Polyfill.io incident, where the risk materialized through a change of domain ownership rather than a technical hack, shows that this assumption is flawed.
Implementing SRI
Generate Hashes
Use the openssl command or the shasum utility to generate SRI hashes:
curl -s https://cdn.example.com/library.js | openssl dgst -sha384 -binary | openssl base64 -A
Or use online SRI hash generators for convenience during development.
Support Multiple Hashes
SRI supports multiple hash algorithms. You can include multiple hashes for forward compatibility:
<script
src="https://cdn.example.com/library.js"
integrity="sha384-hash1 sha512-hash2"
crossorigin="anonymous"
></script>
The browser uses the strongest supported algorithm.
Integrate Into Build Pipeline
Automate SRI hash generation in your build process. When your application references a CDN resource, the build pipeline should fetch the resource, compute the hash, and embed it in the HTML template.
Monitor for SRI Violations
Browsers report SRI failures through the CSP reporting mechanism. Configure CSP reporting to collect and alert on SRI violations. A sudden increase in SRI violations across multiple users indicates a potential CDN compromise.
Fallback Strategy
When SRI blocks a modified resource, your page may break. Implement a fallback that loads the resource from your own origin if the CDN version fails SRI verification:
<script
src="https://cdn.example.com/library.js"
integrity="sha384-hash"
crossorigin="anonymous"
onerror="loadFallback()"
></script>
SRI Limitations
SRI only protects resources loaded with script or link tags. It does not protect dynamically loaded scripts (via document.createElement('script')), images, fonts, or other resource types. For comprehensive content integrity, combine SRI with Content Security Policy.
SRI also does not protect against the CDN serving a valid older version of a library with known vulnerabilities. The hash matches the old version, so SRI allows it. To protect against version downgrade attacks, monitor which version of each library your application loads and alert on unexpected changes.
How Safeguard.sh Helps
Safeguard.sh tracks the third-party dependencies in your web applications, including CDN-hosted scripts. It monitors for vulnerable library versions, verifies that your SRI hashes correspond to the expected library versions, and alerts when CDN-hosted dependencies have known security issues. When a CDN is compromised or a library version has a vulnerability, Safeguard.sh ensures you have complete visibility into which applications are affected.