FSD Frontend System Design

Part II β€” The Shield Β· Lesson 3.13

Subresource Integrity (SRI)

In one linePin a cryptographic hash to every CDN script, so altered code simply refuses to run.

Where you've seen itAny <script src="https://cdn.example.com/chart.min.js"> β€” you're executing whatever that host serves today.

  • Time11 min
  • DiagramHash comparison at load time
  • Chapter3 Β· Security

Diagram

diagram
WITHOUT SRI β€” you execute whatever arrives

  <script src="https://cdn.x.com/lib.js"></script>
                        β”‚
       CDN compromised, β”‚ or DNS hijacked, or a rogue employee
                        β–Ό
              lib.js + skimmer code ──► runs with full origin powers


WITH SRI β€” the browser checks before executing

  <script src="https://cdn.x.com/lib.js"
          integrity="sha384-oqVuAfXRKap7fdgcCY5uykM6+..."
          crossorigin="anonymous"></script>

   download ──► SHA-384 hash ──► compare
                                   β”‚
                    β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”΄β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”
                  match                       mismatch
                    β”‚                             β”‚
                 execute                    BLOCK + console error
                                            (nothing runs, page continues)
diagram
GENERATING THE HASH

  openssl dgst -sha384 -binary lib.js | openssl base64 -A

  β†’ prefix with the algorithm:  integrity="sha384-<base64>"
  β†’ multiple hashes allowed:    integrity="sha384-a... sha512-b..."
                                (any one matching is accepted)

How it works

  1. Compute the hash of the exact file version you tested.
  2. Put it in the integrity attribute on the <script> or <link>.
  3. Add crossorigin="anonymous" β€” without it the browser can't read the cross-origin response to verify it, and the resource is blocked.
  4. If the bytes change by even one character, the browser blocks the resource and logs a console error.
  5. Have a fallback for the blocked case, or a blocked CDN becomes a broken page.
html
<script src="https://cdn.x.com/lib.js"
        integrity="sha384-oqVuAfXRKap7fdgcCY5uykM6+R9GqQ8K"
        crossorigin="anonymous"></script>
<script>window.Lib || document.write('<script src="/vendor/lib.js"><\/script>')</script>

Trade-offs

Use SRI whenIt doesn't work when
Loading from a public CDNThe file is versionless and changes (@latest)
The exact version is pinnedThe CDN serves per-browser variants
Third-party widget with stable buildsContent is generated per request

The honest alternative: self-host the dependency. Then you control the bytes, SRI becomes unnecessary, and you also drop a DNS lookup and a TLS handshake. On HTTP/2 the old "CDN is faster" argument is largely gone.

Interview angle

"Does SRI prevent supply-chain attacks?"

  • It prevents delivery-time tampering β€” a compromised CDN or MITM serving different bytes.
  • It does not help if the package was already malicious when you hashed it (see 3.7) or if the URL is versionless.
  • Pair it with CSP require-sri-for where supported, and prefer self-hosting pinned versions.

Recap

  • One attribute turns "trust the CDN" into "trust this exact file".
  • crossorigin="anonymous" is mandatory or verification can't happen.
  • SRI covers tampering in transit; it can't validate code that was hostile from the start.