Subresource Integrity for CDN-Hosted Assets and Third-Party Scripts
When a web application loads a script from a CDN, it trusts that the CDN serves the correct, unmodified file. That trust is often misplaced. CDN infrastructure can be compromised, cached files can be corrupted through cache poisoning attacks, and man-in-the-middle attackers can modify resources in transit despite TLS encryption (through compromised CAs or downgrade attacks). Subresource Integrity (SRI) eliminates this trust assumption by letting the browser cryptographically verify every external resource before executing it.
How Subresource Integrity Works
SRI adds a cryptographic hash of the expected file content to the HTML element that loads the resource. The browser downloads the file, computes its hash, and compares it to the expected hash in the integrity attribute. If the hashes match, the browser uses the resource. If they do not match, the browser blocks the resource entirely — the script does not execute, the stylesheet does not apply.
The SRI hash is expressed as a base64-encoded cryptographic digest preceded by the algorithm name: sha384-oqVuAfXRKap7fdgcCY5uykM6+R9GqQ8K/uxy9rx7HNQlGYl1kPzQho1wx4JwY8wC. The browser computes the same hash on the downloaded content and compares. The hash algorithm must be one of SHA-256, SHA-384, or SHA-512 — SHA-384 is recommended as the default balance of security strength and computation cost.
SRI Syntax
For scripts loaded from a CDN edge server:
<script src="https://cdn.example.com/framework-3.2.1.min.js"
integrity="sha384-oqVuAfXRKap7fdgcCY5uykM6+R9GqQ8K..."
crossorigin="anonymous"></script>
For stylesheets loaded from a CDN:
<link rel="stylesheet" href="https://cdn.example.com/styles-1.0.css"
integrity="sha384-Li9vy3DqF8tnTXuia..." crossorigin="anonymous">
Two attributes are required: integrity (the hash) and crossorigin (required for cross-origin resources to enable CORS-based response reading). Without crossorigin, the browser cannot compute the hash of a cross-origin resource and SRI verification fails silently.
The crossorigin Attribute Requirement
SRI verification requires the browser to read the response body in order to compute the hash. For cross-origin resources (anything loaded from a different domain, including CDN-hosted assets), the browser enforces the Same-Origin Policy by default, treating the response as opaque — the script executes but the browser cannot inspect its content.
| Metric | Edge Processing | Origin Processing | Improvement |
|---|---|---|---|
| Latency (p50) | 8–15 ms | 120–300 ms | 15–20x faster |
| Cache Hit Ratio | 85–95% | N/A | Reduces origin load |
| TLS Handshake | 1–5 ms (nearby PoP) | 50–150 ms | 10–30x faster |
| Bandwidth Cost | $0.01–0.04/GB | $0.05–0.12/GB | 3–5x cheaper |
| Availability | 99.99% (multi-PoP) | 99.9% (single DC) | 10x fewer outages |
The crossorigin attribute switches the resource load to a CORS request. The CDN must respond with CORS headers (Access-Control-Allow-Origin) for the request to succeed. With CORS, the browser can read the response body, compute the SRI hash, and verify integrity.
crossorigin Values
crossorigin="anonymous" sends a CORS request without credentials (no cookies, no client certificates). This is the correct choice for public CDN-hosted assets that do not require authentication. Most CDN providers configure their edge servers to allow anonymous CORS requests by default.
crossorigin="use-credentials" sends a CORS request with credentials. This is needed only for CDN-hosted resources that require authentication (rare for public scripts and stylesheets). The CDN must respond with Access-Control-Allow-Credentials: true and an explicit origin (not wildcard) for this to work.
SRI Hash Generation Pipeline
Generating SRI hashes must be integrated into the build and deployment pipeline. Manual hash generation is error-prone and does not scale to applications with dozens of CDN-hosted assets.
Build-Time Hash Generation
Modern build tools generate SRI hashes as part of the asset build process. Webpack's webpack-subresource-integrity plugin computes hashes for all emitted assets and inserts the integrity attribute into the generated HTML. Vite and Rollup have equivalent plugins. The build output includes HTML with SRI-protected script and link tags, ready for deployment.
The hash must be computed from the exact bytes that the CDN will serve. If the CDN applies any transformation to the file — compression, minification, character encoding conversion — the hash of the transformed content will not match the hash of the original build output. For SRI to work reliably, the CDN must serve files byte-for-byte identical to the build output, or the hash must be computed from the CDN-transformed content.
Content-Encoding and SRI
CDN performance optimization typically includes content compression (gzip, Brotli). SRI verification operates on the decompressed response body, not the compressed bytes. The browser decompresses the response before computing the SRI hash. This means the SRI hash is always computed from the uncompressed content, regardless of the CDN's content-encoding. No special handling is needed for compressed CDN responses.
Multiple Hash Algorithms
The integrity attribute supports multiple space-separated hashes. The browser selects the strongest algorithm and uses that for verification. This supports algorithm migration: when upgrading from SHA-256 to SHA-384, the tag can include both hashes during the transition period:
integrity="sha256-abc... sha384-xyz..."
The browser uses SHA-384 (stronger) and ignores SHA-256. After all clients have updated to support SHA-384, the SHA-256 hash can be removed.
Server-Side SRI Verification at CDN Edge
Browser-side SRI catches integrity failures at the client. But the damage is already partially done — the corrupted or malicious content has been served by the CDN, and browsers that do not support SRI (older browsers, WebViews, bot crawlers) receive the tampered content without any verification.
CDN edge workers can implement server-side integrity verification as a defense-in-depth measure. The edge worker computes the hash of cached resources before serving them and compares against known-good hashes stored in edge KV. If the hash does not match (indicating cache corruption, storage failure, or tampering), the edge worker takes corrective action: purging the corrupted cache entry, fetching a fresh copy from the origin, or serving a cached known-good version.
Performance Considerations
Computing SHA-384 for every served resource adds CPU overhead at the edge. For large assets (JavaScript bundles over 1MB), the hash computation can take 5–10ms. To balance security and performance, the edge worker can verify integrity periodically (every N requests or every T seconds) rather than on every response, cache the verification result with a short TTL, and skip verification for resources below a minimum size threshold (small assets are less likely to be targeted and faster to re-fetch if corrupted).
SRI for Third-Party Scripts
Third-party scripts — analytics, A/B testing, customer support widgets, advertising — are the highest-risk assets for integrity verification. A compromised third-party script has full access to the page's DOM, cookies, and user data. SRI pins the exact content of the third-party script, ensuring that even if the third-party's infrastructure is compromised, the browser will not execute the modified script.
The Update Challenge
Third-party scripts update frequently — analytics providers push weekly updates, A/B testing platforms update daily. Each update changes the file content, invalidating the SRI hash. The application must update its HTML with the new hash after every third-party script update, creating a maintenance burden.
CDN architectures mitigate this through automated hash monitoring. The edge worker or a background job periodically fetches the third-party script, computes its hash, and compares it to the hash in the HTML. When the hash changes (indicating a script update), the system generates a new integrity attribute, updates the HTML template in the CDN cache, and alerts the operations team. The update can be automated for trusted third-party providers or gated behind manual approval for higher-risk providers.
Version-Pinned URLs
The most robust approach to third-party SRI is version-pinned URLs. Instead of loading analytics.example.com/tracker.js (which may serve different content over time), load analytics.example.com/tracker-3.2.1.js (a version-specific URL that never changes). The SRI hash for a version-pinned URL is stable — it only needs to be computed once when the version is adopted.
Not all third-party providers offer version-pinned URLs. For those that do not, the CDN can proxy the third-party script: the edge worker fetches the script from the third-party, caches it with its hash, and serves it from the CDN's own domain. The SRI hash is computed from the cached version, which does not change until the CDN explicitly fetches a new version. This converts an uncontrolled third-party update into a controlled CDN deployment.
SRI Failure Handling
When SRI verification fails, the resource is blocked and the application may break. CDN architectures should implement graceful failure handling rather than letting SRI failures result in a broken user experience.
Fallback Loading
The HTML can include a fallback script tag that loads from an alternative source. The primary script tag loads from the CDN with SRI. If SRI verification fails (the onerror event fires), a fallback script tag loads the same resource from the origin server or a different CDN. This pattern is only useful for script elements, not for link elements (stylesheets), due to browser event handling differences.
CDN Edge Detection
The CDN edge worker can detect scenarios likely to cause SRI failures: the origin returned a different version of the file than the one the HTML expects (version skew between HTML deployment and asset deployment), the cached file has been corrupted (bitrot or storage failure), or the CDN applied an unexpected transformation (encoding conversion, whitespace normalization). The edge worker can take corrective action before the response reaches the browser, reducing SRI failure rates to near zero.
SRI Adoption Best Practices for CDN Deployments
Start SRI adoption with the highest-risk assets: third-party scripts that have access to user data, authentication-related scripts that handle tokens and credentials, and payment processing scripts that interact with financial data. These assets have the highest impact if compromised and the most to gain from integrity verification.
Expand SRI coverage to all first-party scripts and stylesheets once the hash generation pipeline is automated. Use Content Security Policy with require-sri-for script style (deprecated but still supported in some browsers) or equivalent enforcement to ensure that new assets without SRI hashes are caught during development and testing.
Monitor SRI failures in production through CDN monitoring. A sudden increase in SRI failures may indicate a CDN cache corruption event, a deployment that updated HTML without updating asset hashes, or a third-party script update that invalidated the pinned hash. Each scenario requires a different response — cache purge, redeployment, or hash update — and the monitoring system should distinguish between them based on the failure pattern.