Using Subresource Integrity to Secure CDN Scripts
Subresource Integrity (SRI) is a web security specification that allows browsers to verify that third-party assets, such as scripts fetched from a Content Delivery Network (CDN), have not been modified or compromised. By defining a cryptographic hash in a webpage's HTML and comparing it against the hash of the downloaded resource, SRI ensures that only authentic, untampered code runs in user browsers. This article breaks down the mechanics of SRI, explains how it mitigates supply chain risks, and demonstrates how to implement it effectively.
The Security Risk of Third-Party CDNs
Web developers frequently rely on public CDNs to host shared libraries like jQuery, React, or Bootstrap. While CDNs improve load times, reduce server bandwidth, and leverage browser caching, they introduce a supply chain vulnerability. If a malicious actor compromises the CDN, alters DNS records, or performs a man-in-the-middle attack, they can inject malicious code directly into the hosted JavaScript files. Because browsers execute downloaded scripts with the full privileges of the host domain, compromised assets can lead to data theft, session hijacking, or site defacement.
How SRI Cryptographic Verification Works
SRI mitigates this risk by turning the browser into an automated integrity checker. The process works in three distinct phases:
- Hash Generation: Before deploying, the developer generates a cryptographic hash (typically SHA-256, SHA-384, or SHA-512) of the original, trusted script file.
- Declaration: The developer places the generated
hash inside the
integrityattribute of the<script>tag within their HTML document. - Validation at Runtime: When a user visits the
webpage, the browser downloads the script from the CDN and computes its
cryptographic hash in memory. The browser then compares this calculated
hash to the hash provided in the
integrityattribute.
If the two hashes match identically, the browser executes the script. If the hashes do not match—meaning the file was modified by even a single character—the browser immediately blocks execution and logs a network security error in the developer console.
Implementing SRI in HTML
To implement SRI, a <script> tag requires two
specific attributes: integrity and
crossorigin.
<script
src="https://cdn.example.com/library/1.0.0/bundle.min.js"
integrity="sha384-oqVuAfXRKap7fdgcCY5uykM6+R9GqQ8K/uxy9rx7HNQlGYl1kPzQho1wx4JwY8wC"
crossorigin="anonymous">
</script>The integrity value consists of the hashing algorithm
prefix (such as sha384-) followed by the base64-encoded
digest of the file. The crossorigin="anonymous" attribute
is mandatory for cross-origin resources. It instructs the browser to
request the resource without sending user credentials (like cookies),
which is required to allow the browser to inspect the response body for
hash verification under Cross-Origin Resource Sharing (CORS) rules.
Managing SRI in Production
Because SRI requires an exact byte-for-byte match, developers must manage updates deliberately:
- Strict Versioning: Never use SRI with dynamic or
unversioned URLs (such as URLs pointing to
latest.js). The hash is tied to a specific file snapshot, so any silent upstream update will cause the script to fail. - Automated Builds: Modern build tools (such as Webpack, Vite, or Rollup) use plugins to automatically generate and inject SRI hashes into HTML templates during the build process, preventing manual calculation errors.
- Fallbacks: If a CDN asset fails to load due to an integrity mismatch or network outage, sites can use inline JavaScript fallbacks to dynamically load a local copy of the script, maintaining application functionality while preserving security.