Chapter 69: Subresource Integrity (SRI) & Referrer Policy

The integrity Attribute on script and link

Exploring the base64 cryptographic hash grammar, multi-hash algorithm negotiation, and resource verification across script and link elements.

LEARNING OBJECTIVES
  • Master the exact grammar and syntax of the HTML integrity attribute.
  • Understand how browsers prioritize and resolve multiple cryptographic hashes on a single tag.
  • Apply SRI verification across <script>, <link rel="stylesheet">, and <link rel="preload"> tags.
  • Diagnose hash resolution rules when mixing SHA-256, SHA-384, and SHA-512 digests.
🎬 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 entering a high-security research facility. To access the laboratory, you must present a biometric identifier. The door lock accepts three types of verification: a thumbprint scan (SHA-256), an iris scan (SHA-384), or a full genomic DNA sequencer (SHA-512).

+---------------------------------------------------------------------------------------+
|                             THE MULTI-TIER SECURITY LOCK                              |
+---------------------------------------------------------------------------------------+
|                                                                                       |
|  Door Access Policy (HTML Attribute):                                                 |
|  integrity="sha256-thumbprint123 sha384-irisScan456 sha512-dnaSequence789"            |
|                                                                                       |
|  Browser Engine Rule:                                                                 |
|  1. Find the STRONGEST algorithm listed (SHA-512).                                    |
|  2. IGNORE the weaker algorithms (SHA-384, SHA-256).                                  |
|  3. Validate the incoming file against the SHA-512 hash only.                         |
|                                                                                       |
+---------------------------------------------------------------------------------------+

If the building security system possesses a DNA sequencer (the strongest available), it will ignore your thumbprint and iris scan completely and demand the DNA test.

Similarly, the HTML integrity attribute allows you to provide multiple space-separated hashes. The browser engine parses all tokens, selects the strongest cryptographic algorithm it supports, and ignores all weaker hashes. If you provide multiple hashes of the same strongest algorithm, the file is accepted if it matches any of them.


Technical Deep Dive & Specifications

Formal W3C Syntax Grammar

The integrity attribute value is defined in the W3C SRI specification as a space-separated list of integrity metadata tokens:

integrity-metadata = *WSP hash-expression *( 1*WSP hash-expression ) *WSP
hash-expression    = hash-algorithm "-" hash-value [ "?" hash-options ]
hash-algorithm     = "sha256" / "sha384" / "sha512"
hash-value         = *base64-value

Each token consists of three parts:

  1. Algorithm Identifier: One of sha256, sha384, or sha512 in lowercase.
  2. Hyphen Separator: A single - character.
  3. Base64 Digest: The binary cryptographic hash of the exact file bytes, encoded in standard Base64 (including trailing = padding).
  sha384-d7zL2...YxK8=
  |____| |___________|
    |          |
Algorithm   Base64 Digest

Supported HTML Elements & Rel Types

The integrity attribute is implemented on two primary HTML elements:

Element & Context Attribute Role Failure Consequence
<script src="..."> Verifies JavaScript code before execution. Script does not execute; window.onerror / script.onerror fires.
<link rel="stylesheet"> Verifies CSS stylesheet before parsing rules into CSSOM. Stylesheet is discarded; page renders without the external styles.
<link rel="preload" as="script|style"> Verifies preloaded asset integrity in the browser cache. Asset is purged from preload cache; subsequent fetches will fail.
<link rel="modulepreload"> Verifies ES module preloads. Module is rejected; dynamic import() or <script type="module"> fails.

⚠️ Note on Stylesheet Subresources: The integrity attribute on <link rel="stylesheet"> verifies the integrity of the .css text file itself. It does not recursively verify assets referenced inside the CSS file (such as @import, url(...) background images, or @font-face web fonts).

The Multi-Hash Resolution Algorithm

When multiple hashes are declared in an integrity attribute, modern browsers execute the following resolution algorithm:

[ Parse all space-separated tokens in the integrity attribute ]
                            |
                            v
   [ Filter out unrecognized algorithms (e.g., md5, sha1) ]
                            |
                            v
   [ Identify the STRONGEST algorithm present in the set ]
            (Ranking: SHA-512 > SHA-384 > SHA-256)
                            |
                            v
 [ Discard all candidate hashes with lower algorithmic strength ]
                            |
                            v
  [ Compute hash of downloaded bytes using strongest algorithm ]
                            |
                            v
   /---------------------------------------------------------\
  <  Does computed hash match ANY of the remaining candidates? >
   \---------------------------------------------------------/
                    /                       \
              YES  /                         \  NO
                  v                           v
          [ Resource Validated ]      [ Resource Rejected ]

Example Scenarios:

  1. Mixed Algorithm Strengths:

    <script src="app.js" integrity="sha256-AAAA sha384-BBBB sha512-CCCC"></script>
    

    Behavior: The browser selects sha512 (the strongest). It completely ignores sha256-AAAA and sha384-BBBB. If app.js matches sha512-CCCC, the script executes.

  2. Multiple Hashes of Equal (Strongest) Strength:

    <script src="bundle.js" integrity="sha384-HASH_V1 sha384-HASH_V2"></script>
    

    Behavior: Both candidates share the strongest algorithm (sha384). The script executes if the downloaded file matches either HASH_V1 or HASH_V2. This enables zero-downtime rolling deployments when CDNs serve new and old versions during cache propagation.


SYS: ACTIVE
HULL: 98%
CORE: STABLE
NET: ONLINE
HTML STARSHIP CODE TERMINAL example.html
LIVE RENDER & DIAGNOSTICS CORE TEMP: 45°C
INSPECTING DOM: VALID
TAGS: SCANNING...

💻 Interactive Code Playground

Starter Code

Line-by-Line Code Breakdown

  • Lines 8–15 (<link rel="preload"...): Preloads animate.min.css into the browser cache. If the preload hash does not match, the browser drops the cached entry immediately.
  • Lines 17–23 (<link rel="stylesheet"...): Applies the verified stylesheet to the DOM. The integrity and crossorigin attributes match the preload declaration, ensuring cache reusability.
  • Lines 41–46 (<script src="..." integrity="sha384-... sha512-..."): Declares two hashes. The browser identifies sha512 as the strongest algorithm, discards the sha384 token, and verifies against the sha512 digest (sha512-WFN04846...).

Expected Browser Render Output


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...
+---------------------------------------------------------------------+
| 🛡️ Verified Subresources Loaded (Bounces into view via CSS animation)|
| Both stylesheet and script are validated via cryptographic digests. |
| Lodash v4.17.21 cryptographically verified and executed.            |
+---------------------------------------------------------------------+

🏋️ Hands-On Exercise

🎯 The Challenge: Configure Zero-Downtime Multi-Hash Deployment

Instructions:

  1. Your continuous delivery pipeline is deploying a new version of vendor.js.
  2. During the 15-minute deployment window, some CDN edge nodes serve Version A, while others serve Version B.
  3. Configure a single <script> element with multi-hash integrity metadata supporting both versions:
    • Version A (SHA-384): sha384-v1AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
    • Version B (SHA-384): sha384-v2BBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBB
  4. Add the appropriate CORS attribute.
  5. Provide a fallback error handler in case a compromised CDN serves a third, unrecognized version.

🏁 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. Accidental Commas in Multi-Hash Lists: Multiple hashes must be separated by spaces, not commas. Using integrity="sha384-AAA, sha384-BBB" causes the browser's Base64 parser to fail, rejecting the entire resource.
  2. Mismatch Between <link rel="preload"> and <link rel="stylesheet">: If you preload a resource with integrity="sha384-XYZ" and then load the stylesheet with a different or missing integrity attribute, the browser cannot reuse the preloaded response and will make a redundant network request.
  3. Assuming CSS Subresources are Protected: Declaring integrity on a stylesheet does NOT verify fonts or background images loaded via @font-face or url() within that stylesheet.

💡 Pro Tips

  1. Zero-Downtime Rolling Releases: When deploying frontend updates across global CDNs with staggered cache invalidation, provide both the current build's hash and the upcoming build's hash in your HTML template for the transition period.
  2. Module Preload with SRI: When building modern ESM applications with <link rel="modulepreload">, always include integrity and crossorigin="anonymous" on the preload tag to guarantee that chunks fetched ahead of time are cryptographically verified before dynamic import execution.

📌 Key Takeaways

  • The integrity attribute contains space-separated tokens formatted as [algorithm]-[base64Digest].
  • Supported algorithms are sha256, sha384, and sha512.
  • When multiple algorithms are specified, the browser evaluates only the strongest algorithm present (SHA-512 > SHA-384 > SHA-256).
  • When multiple hashes of the same strongest algorithm are provided, the resource is accepted if it matches any of them.
  • The attribute is supported on <script>, <link rel="stylesheet">, <link rel="preload">, and <link rel="modulepreload">.
  • --
⭐ LEARN: HTML 🌟 ⚔️ QUIZ BATTLE ARENA // ACTIVE
3x
STREAK!
BONUS ACTIVE
COMBO
? Question 1 / 3

If an HTML element has integrity="sha256-AAA sha512-BBB", and the downloaded resource matches hash AAA but fails hash BBB, what will the browser do?

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

What character must be used to separate multiple cryptographic hashes inside an integrity attribute?

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

Which of the following resources is NOT cryptographically validated when you attach integrity="sha384-..." to <link rel="stylesheet">?

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