Subresource Integrity Pins External Assets to Expected Content
A page that loads JavaScript or CSS from another host gives that host a direct path into the page’s execution or presentation context. HTTPS protects the transfer against network tampering, but it does not tell the browser whether the server returned the exact asset the application intended to use.
Subresource Integrity (SRI) adds a content check. The document carries cryptographic metadata for a resource. After fetching the bytes, the browser computes the relevant digest and compares it with the metadata before accepting the resource.
<script
src="https://cdn.example.net/app.min.js"
integrity="sha384-BASE64_DIGEST"
crossorigin="anonymous"></script>The digest is tied to the resource bytes, not merely to its URL. A response with different bytes fails the integrity check even when it arrives from the expected hostname over a valid TLS connection.
Integrity metadata is a content commitment
An integrity value contains one or more hash expressions. Each expression names a supported hash algorithm and carries a base64-encoded digest.
sha384-BASE64_DIGESTFor current SRI metadata, the defined algorithm prefixes include sha256, sha384, and sha512. When metadata contains recognized hashes from algorithms of different strengths, browser processing selects the strongest applicable algorithm set and compares the fetched resource against hashes in that set.
Multiple hashes using the selected algorithm can support an intentional transition between known asset versions. A match against an eligible digest permits the integrity check to succeed; a mismatch causes the resource load to fail.
That behavior makes the HTML document a declaration of acceptable content rather than a declaration that any bytes at a particular URL are acceptable.
Cross-origin SRI also depends on CORS
Integrity checking does not bypass cross-origin fetch rules. For a resource fetched from another origin, SRI requires the response to satisfy CORS. A common script form therefore combines integrity with crossorigin="anonymous".
<script
src="https://static.example.net/runtime.js"
integrity="sha384-BASE64_DIGEST"
crossorigin="anonymous"></script>The resource server must return an appropriate Access-Control-Allow-Origin response header. If the cross-origin response is not eligible for the required CORS processing, the browser cannot simply treat the integrity hash as permission to consume it.
This separates two checks: CORS governs whether the cross-origin response may be exposed for the load, while SRI checks whether its content matches approved metadata.
Asset updates require metadata updates
A content hash changes when the protected bytes change. That property is central to SRI, but it also creates an operational dependency between asset publication and HTML deployment.
If a CDN replaces runtime.js with a new build while the document still carries the old digest, browsers reject the new bytes. If the document is updated with a new digest before the new asset is consistently available, clients may encounter the opposite mismatch.
Versioned asset URLs reduce this coordination problem:
/assets/runtime.4f29c1.js
/assets/runtime.91a720.jsA deployment can publish the new immutable asset first, then publish markup that references its URL and digest. Keeping old versioned assets available during cache turnover also avoids forcing one URL to represent several byte sequences.
SRI therefore fits most cleanly with immutable or explicitly versioned static assets.
A valid hash does not make code safe
SRI verifies byte equality against metadata supplied by the document. It does not inspect the JavaScript for malicious behavior, prove that a dependency is free of defects, or establish that the party that produced the expected digest was trustworthy.
If an attacker can alter both the resource and the page containing its integrity metadata, the attacker may replace both values. SRI is most useful when the protected document and the external asset do not share the same compromise boundary.
The control is also distinct from Content Security Policy. CSP can constrain permitted script sources and execution patterns. SRI can pin a selected external resource to expected bytes. Deployments may use both because they enforce different conditions.
Build pipelines should derive hashes from release artifacts
Hand-maintained integrity strings are easy to desynchronize from the files they protect. A release pipeline can compute metadata from the exact artifact that will be published, then place that value into generated markup or a manifest consumed by the site build.
A generic digest pipeline has this shape:
release artifact
|
+--> publish immutable bytes
|
+--> compute digest
|
v
integrity metadata
|
v
generated markupThe important property is provenance: the digest must correspond to the same bytes that reach the asset host. Rebuilding an ostensibly identical package in a separate step can produce different bytes when the build is not reproducible.
Validation can fetch the deployed asset, compute its digest, and compare it with the markup before a release is promoted. This catches publication mistakes without changing the browser’s enforcement role.
Coverage matters more than isolated adoption
Adding SRI to one script leaves other eligible external assets outside that content check. An asset inventory can identify scripts and linked resources that cross trust boundaries, then record which ones carry integrity metadata and which are intentionally excluded.
SRI applies to script elements and to supported link relationships such as stylesheets, preloads, and module preloads. Browser support and the exact fetch mode still matter for each resource type.
A practical review should also account for assets injected at runtime. Static HTML checks alone may miss resources assembled by application code or third-party loaders.
SRI narrows trust in an external host
Without SRI, a page loading an eligible external asset generally accepts the bytes returned for that request, subject to the browser’s other security controls. With valid integrity metadata, the page can require those bytes to match a declared cryptographic digest.
That boundary is narrow by design. It does not secure the dependency lifecycle or replace source review, CSP, CORS, TLS, artifact signing, or deployment controls. It gives the browser one precise condition at load time: the fetched resource must be one of the byte sequences the document explicitly accepts.
References
- MDN, Subresource Integrity: https://developer.mozilla.org/en-US/docs/Web/Security/Defenses/Subresource_Integrity
- W3C, Subresource Integrity: https://www.w3.org/TR/SRI/