LEARNING OBJECTIVES ⌵
- Master the exact grammar and syntax of the HTML
integrityattribute. - 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.
📖 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:
- Algorithm Identifier: One of
sha256,sha384, orsha512in lowercase. - Hyphen Separator: A single
-character. - 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
integrityattribute on<link rel="stylesheet">verifies the integrity of the.csstext file itself. It does not recursively verify assets referenced inside the CSS file (such as@import,url(...)background images, or@font-faceweb 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:
Mixed Algorithm Strengths:
<script src="app.js" integrity="sha256-AAAA sha384-BBBB sha512-CCCC"></script>Behavior: The browser selects
sha512(the strongest). It completely ignoressha256-AAAAandsha384-BBBB. Ifapp.jsmatchessha512-CCCC, the script executes.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 eitherHASH_V1orHASH_V2. This enables zero-downtime rolling deployments when CDNs serve new and old versions during cache propagation.
💻 Interactive Code Playground
Starter Code
Line-by-Line Code Breakdown
- Lines 8–15 (
<link rel="preload"...): Preloadsanimate.min.cssinto 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. Theintegrityandcrossoriginattributes match the preload declaration, ensuring cache reusability. - Lines 41–46 (
<script src="..." integrity="sha384-... sha512-..."): Declares two hashes. The browser identifiessha512as the strongest algorithm, discards thesha384token, and verifies against thesha512digest (sha512-WFN04846...).
Expected Browser Render Output
+---------------------------------------------------------------------+
| 🛡️ 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:
- Your continuous delivery pipeline is deploying a new version of
vendor.js. - During the 15-minute deployment window, some CDN edge nodes serve Version A, while others serve Version B.
- 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
- Version A (SHA-384):
- Add the appropriate CORS attribute.
- Provide a fallback error handler in case a compromised CDN serves a third, unrecognized version.
🏁 Starter Code Sandbox
⚠️ Common Pitfalls
- 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. - Mismatch Between
<link rel="preload">and<link rel="stylesheet">: If you preload a resource withintegrity="sha384-XYZ"and then load the stylesheet with a different or missingintegrityattribute, the browser cannot reuse the preloaded response and will make a redundant network request. - Assuming CSS Subresources are Protected: Declaring
integrityon a stylesheet does NOT verify fonts or background images loaded via@font-faceorurl()within that stylesheet.
💡 Pro Tips
- 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.
- Module Preload with SRI: When building modern ESM applications with
<link rel="modulepreload">, always includeintegrityandcrossorigin="anonymous"on the preload tag to guarantee that chunks fetched ahead of time are cryptographically verified before dynamic import execution.
📌 Key Takeaways
- The
integrityattribute contains space-separated tokens formatted as[algorithm]-[base64Digest]. - Supported algorithms are
sha256,sha384, andsha512. - 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">. - --