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:

  1. Hash Generation: Before deploying, the developer generates a cryptographic hash (typically SHA-256, SHA-384, or SHA-512) of the original, trusted script file.
  2. Declaration: The developer places the generated hash inside the integrity attribute of the <script> tag within their HTML document.
  3. 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 integrity attribute.

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.