FlowingDev

SRI, explained: the digital fingerprint for your website's assets

Learn how Subresource Integrity (SRI) uses cryptographic hashes to protect your site from malicious scripts and styles served by third-party CDNs.

Try the tool: SRI Hash Generator

In one sentence

Subresource Integrity (SRI) is a security feature that lets browsers verify that the files they fetch from external sources, like CDNs, haven't been secretly tampered with.

The problem it solves

Picture this: you're building a sleek new web app. To make it zippy, you use a Content Delivery Network (CDN) to serve common libraries like React, Vue, or even just some fancy fonts. This is standard practice. Your users get a faster experience because the file is likely already cached in their browser from visiting another site, or it's served from a server physically closer to them. Win-win, right?

Mostly. But you've just introduced a massive element of trust. You are trusting that the CDN provider will always serve the exact file you intended. What if that CDN gets hacked? An attacker could replace the friendly, helpful react.min.js with a malicious version: react.min.js-plus-a-crypto-miner-and-password-stealer.

Suddenly, this malicious code is running on your website, with the full trust of your users' browsers. It can slurp up login credentials, deface your pages, or enlist your visitors into a botnet. This is a classic supply-chain attack, and it's terrifying because you didn't do anything wrong on your own server. You just trusted the wrong party at the wrong time.

Before SRI, there was no native browser mechanism to defend against this. Developers used workarounds, but they were clunky. SRI was created by the W3C to solve this specific problem head-on. It provides a simple, standardized way to tell the browser, "Hey, go fetch this script, but before you run it, make absolutely sure it's the one I'm expecting. If it's even one byte off, drop it like it's hot and tell me about it."

How it works under the hood

SRI is a clever marriage of a simple HTML attribute and some serious cryptographic principles. Let's break it down.

The integrity attribute

The magic starts with a new attribute you can add to your <script> and <link> tags. It's called, fittingly, integrity.

<script
  src="https://code.jquery.com/jquery-3.6.0.min.js"
  integrity="sha384-oBqDVmMz9ATKxIep9tiCxS/Z9fNfEXiDAYTujMAeBAsjFuCZSmKbSSUnQlmh/jp3"
  crossorigin="anonymous"></script>

This attribute holds a string containing two parts: a hash algorithm prefix (here, sha384-) and a Base64-encoded cryptographic hash. This is the "digital fingerprint" of the file you expect to receive.

The Hash: A Digital Fingerprint

A cryptographic hash function is a mathematical algorithm that takes an input (like the entire content of a JavaScript file) and produces a short, fixed-size string of characters, called a hash. Think of it like a super-powered checksum.

These hashes have a few crucial properties:

  • Deterministic: The same input file will always produce the exact same hash.
  • Avalanche Effect: Change just a single character in the input file—add a space, change a variable name—and the resulting hash will be completely different and unrecognizable.
  • One-way: It's practically impossible to reverse the process. You can't take the hash and figure out what the original file content was.

The SRI standard supports three secure hash algorithms: SHA-256, SHA-384, and SHA-512. The number refers to the bit-length of the hash, and bigger is generally stronger. SHA-384 is a great all-around choice.

So, when you're about to link to a CDN file, you first generate its hash. You are essentially taking a snapshot of the file at that moment and telling the browser, "This is what the real jquery-3.6.0.min.js looks like."

The crossorigin attribute

See that crossorigin="anonymous" in the example? It’s not just for decoration; it's mandatory. For a browser to fetch a resource from a different origin (e.g., your site my-app.com fetching a script from code.jquery.com) and inspect its contents for the SRI check, it needs permission via Cross-Origin Resource Sharing (CORS).

Setting crossorigin="anonymous" tells the browser to make the request without sending any user credentials like cookies or HTTP authentication headers. This is a security and privacy must-have. If you forget this attribute, the browser will refuse to perform the integrity check and will simply block the resource from loading, leading to a broken site.

Putting It All Together: The Browser's Checklist

When a browser encounters a tag with an integrity attribute, it follows this strict protocol:

  1. It sees the <script> tag and notes the src, integrity, and crossorigin attributes.
  2. It sends a request for the file at the src URL. Thanks to crossorigin, this is a CORS request.
  3. The file is downloaded.
  4. Crucially, before executing anything, the browser calculates its own hash of the downloaded file's content, using the same algorithm specified in the integrity attribute (e.g., sha384).
  5. It then compares its freshly-calculated hash with the hash you provided in the attribute.
  6. If they match: Hooray! The file is authentic. The browser executes the script or applies the stylesheet.
  7. If they don't match: RED ALERT! The browser assumes the file has been tampered with. It completely discards the file and does not execute it. It then fires a Failed to find a valid digest error to the developer console. Your site might look broken (e.g., a missing chart or font), but you've successfully dodged a bullet.

Real-world stories

The Defaced Analytics Dashboard

A marketing team relied on a dashboard that used a third-party charting library, pulled from a niche CDN, to visualize their campaign data. The developer, having just read up on security best practices, had added SRI hashes to the library's <script> tag. One Monday morning, the CDN suffered a brief compromise. An attacker replaced the popular charting library with a script that just displayed a giant, mocking ASCII art face.

When the marketing team loaded their dashboard, the charts were broken. They saw empty boxes. They called IT, annoyed. The developer checked the browser console and saw the beautiful, beautiful SRI validation error. The browser had detected the modified file, refused to run it, and prevented the defacement. Instead of a major security incident and a panicked C-suite, it was a 15-minute investigation that ended with temporarily pointing to a different CDN.

Lesson: SRI turns a potential security catastrophe into a containable availability problem.

The Sneaky Crypto-Miner

A popular, lightweight JavaScript utility library hosted on a free CDN was a favorite of indie developers. An attacker gained access to the CDN and modified the library file, adding a few obfuscated lines of code that fired up a WebAssembly crypto-miner. The file size barely changed, and the library's core functions still worked perfectly.

Websites using the library without SRI suddenly started causing their users' laptops to spin up their fans and drain their batteries. Users complained about sluggishness, but it was hard to diagnose. The sites themselves looked fine. However, sites that had implemented SRI were immune. Their browsers blocked the modified script, and while the utility functions broke, their users' CPUs were safe.

Lesson: SRI catches not just obvious defacements but also subtle, parasitic attacks that can damage your site's reputation.

The Forgotten Font Update

A designer insisted on using a specific version of a font from a third-party font foundry, served via their CDN. The developer dutifully copied the <link> tag, complete with its SRI hash. The site launched and looked great. Six months later, the foundry updated the font file to add new currency symbols and improve kerning. It was a legitimate, helpful update.

Suddenly, the site's text reverted to ugly, default Arial. The developer was baffled until they checked the console and saw the SRI error. The browser was correctly blocking the new, modified font file because its hash no longer matched the old one in the HTML. The "attack" was just a benign update, but SRI did its job. The fix was simple: generate a new hash for the updated font and deploy the change.

Lesson: SRI enforces strict versioning. It protects you from malicious changes and unexpected upstream updates, forcing you to be intentional about the assets you use.

Common mistakes and traps

  • Forgetting crossorigin="anonymous". This is the #1 mistake. Without it, the browser doesn't have CORS permission to inspect the resource, so for security, it just blocks it. No integrity check happens. Your script or style simply fails to load.
  • Hashing the wrong thing. You must hash the exact file content that the browser receives. Don't hash a local, uncompressed version of a script if you're linking to the minified CDN version. Don't hash the URL string itself. You need the hash of the file's body.
  • Using weak hash algorithms. MD5 and SHA-1 have known vulnerabilities and should not be used for security purposes. The spec requires browsers to support at least SHA-256, SHA-384, and SHA-512. Stick with those.
  • Not updating the hash after a legitimate update. SRI is a feature, not a bug. If the file you're linking to is updated for any reason, you must generate a new integrity hash and update your HTML integrity attribute. Failure to do so will result in the resource being blocked.
  • Thinking it protects your own server. SRI is designed to validate third-party resources. If an attacker has compromised your server enough to alter your HTML files, they can just change the SRI hash to match their malicious script. It provides no benefit for same-origin resources.

Why it belongs on your radar

You should think about SRI every single time you write a <script src="..."> or <link rel="stylesheet" href="..."> that points to a domain you don't control.

It's a foundational piece of modern web security. In a world built on NPM, CDNs, and a complex web of third-party dependencies, your supply chain is a massive attack surface. SRI is one of the simplest and most effective tools for hardening that surface. It's your first line of defense against a compromised CDN. Paired with a Content Security Policy (CSP), it provides robust, layered protection.

Adding SRI takes a few extra seconds when you add a resource, but it can save you from a world of hurt down the road. It transforms a silent, dangerous exploit into a loud, safe failure.

Go deeper

Theory done. Time to get your hands dirty — 100% in your browser.

Try the tool: SRI Hash Generator