Application Security

Subresource Integrity Failures: When CDN Trust Goes Wrong

SRI protects against CDN compromises and supply chain attacks on client-side scripts. Most web applications do not use it. Here is what they are missing.

Michael
Security Architect
5 min read

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.

Never miss an update

Weekly insights on software supply chain security, delivered to your inbox.