Subresource Integrity Pins Browser-Loaded Assets to Approved Bytes

A web page can load executable code from infrastructure outside the application’s deployment boundary. A <script> URL may point to a CDN, a package distribution endpoint, or another origin operated under a separate release process. TLS protects the connection to that endpoint, but a valid HTTPS response can still contain bytes different from the version the page author intended to run.

Subresource Integrity, commonly shortened to SRI, adds a content check at the browser. The document carries cryptographic digest metadata for a resource. After fetching the resource, the browser computes the applicable digest and compares it with the metadata before accepting the resource for the protected use.

The control is deliberately narrow. It pins expected content, not the identity or operational quality of the hosting service.

The integrity value describes expected content

For a script, integrity metadata is placed in the integrity attribute:

<script
  src="https://cdn.example.net/app.min.js"
  integrity="sha384-BASE64_DIGEST"
  crossorigin="anonymous"></script>

The metadata entry combines a supported hash algorithm name with a Base64-encoded digest. SHA-256, SHA-384, and SHA-512 are defined for current SRI use. The digest must be computed over the exact resource representation expected by the browser.

A one-byte difference produces a different digest with overwhelming probability for these cryptographic hash functions. Minification, a rebuilt source map comment, line-ending conversion, banner changes, or an automatic CDN transformation can therefore invalidate metadata even when the resulting program appears functionally equivalent.

That sensitivity is the point. SRI is not asking whether two programs behave similarly. It checks whether fetched bytes match content approved when the metadata was produced.

A mismatch prevents the protected resource from being accepted

When integrity metadata applies, the browser does not treat a successful HTTP response as sufficient. It evaluates the response against the integrity metadata. If no applicable digest matches, the protected resource is rejected rather than executed or applied as though the check had passed.

This changes one failure mode for externally hosted JavaScript. Without a content pin, control of the resource URL can be enough to replace code delivered to visitors. With correct SRI metadata, replacement bytes also need to satisfy the digest listed by the document.

SRI does not make a compromised resource harmless. An attacker who can also alter the HTML or response headers that supply the integrity metadata may be able to replace both the resource and its expected digest. The useful trust separation exists when the document and the pinned resource do not share the same uncontrolled modification path.

The same distinction applies to deployment credentials. If one credential can publish the application HTML and the external asset, a digest does not create an independent approval boundary against compromise of that credential.

Cross-origin integrity checks interact with CORS

Cross-origin SRI is tied to CORS processing. A browser needs a CORS-enabled response for a cross-origin resource whose content is being subjected to an integrity check. Markup commonly sets crossorigin="anonymous" while the resource server returns an appropriate Access-Control-Allow-Origin header.

This requirement is operationally important. Adding an integrity value while leaving the CDN’s CORS configuration incompatible can turn a security rollout into a production load failure.

The crossorigin attribute is not itself the integrity check. It selects CORS behavior for the request. The digest comparison remains the mechanism that binds the fetched representation to the metadata.

Same-origin and cross-origin deployment paths should therefore be tested as the browser will request them, including redirects, response headers, caching layers, and transformations that can change the final bytes.

Multiple digests can support controlled transitions

An integrity attribute can contain multiple metadata entries separated by whitespace. This can be useful when a deployment deliberately permits more than one approved representation during a transition.

Multiple entries should not become an unbounded history of old releases. Every accepted digest expands the set of representations that can pass the check. If an older build contains code that is no longer meant to execute, retaining its digest preserves an acceptance path for that build.

Algorithm selection also matters when metadata contains entries using different hash functions. Browser processing follows the SRI rules for selecting applicable metadata rather than treating every listed algorithm as an independent downgrade path. Deployment tooling should generate metadata according to the current specification and verify the result in target browsers.

A simpler release process often produces one immutable asset URL and its corresponding digest together, then updates the document in the same release transaction.

Mutable URLs create release friction

SRI fits naturally with immutable assets. A URL such as:

/assets/vendor.4f31c2.js

can identify a fixed artifact, while the HTML carries the digest for that artifact. A new build gets a new asset identity and new metadata.

A mutable URL such as:

https://cdn.example.net/library/latest.js

creates a different contract. If the provider changes the file while the application still carries the old digest, browsers reject the new bytes. Updating the external file independently from the document is incompatible with a content pin that intentionally expects a specific representation.

That friction is useful when silent dependency changes are not acceptable. It also means teams need release ownership for digest updates instead of copying SRI metadata once and assuming the URL can keep changing behind it.

The digest must come from a trusted build path

A digest only states equality with the bytes used to calculate it. If those bytes were already malicious, SRI faithfully pins malicious content.

The generation step therefore belongs inside the software supply-chain boundary. A build pipeline can fetch or produce the intended artifact, verify its provenance according to project policy, calculate the digest, and emit the HTML metadata. Review can then cover both the dependency change and the new integrity value.

Generating the digest from whatever a production CDN happens to return after a release can invert that relationship. The CDN response becomes the authority for expected content instead of a distribution copy of an already approved artifact.

For third-party libraries, versioned and immutable distribution paths make this boundary easier to audit. The project still needs its normal dependency review, update policy, and vulnerability response process; SRI does not replace them.

SRI and CSP protect different decisions

Content Security Policy and SRI are often deployed together, but they answer different questions. CSP constrains which resource sources or script execution paths the document permits. SRI verifies that a protected fetched resource matches approved content.

A CSP rule may permit scripts from a CDN origin. That origin-level permission does not pin one file version. SRI can add a byte-level constraint for a selected resource from that allowed origin.

Conversely, a matching SRI digest does not override CSP. A resource still has to satisfy the document’s applicable CSP directives and other browser checks. Layering the controls is useful because source authorization and content verification address separate failure paths.

Pinning content shifts responsibility into release engineering

SRI works best when integrity metadata is treated as generated release data rather than hand-maintained decoration. Asset bytes and their digests need to move together. Build reproducibility, immutable naming, cache behavior, CORS configuration, and rollback procedures all affect whether that pairing remains valid in production.

Rollback deserves explicit handling. Restoring an older HTML document while its matching asset has been deleted can fail even though the digest is correct. Restoring an older asset under a mutable URL while current HTML expects newer bytes fails for the opposite reason. Retaining versioned assets for the supported rollback window avoids both mismatches.

The security property remains precise: the browser accepts a protected resource only when the fetched representation satisfies the integrity metadata and the surrounding browser policy permits the load. That check can contain damage from unauthorized changes at a resource host, but only while the metadata, document delivery path, and release process preserve a separate trusted statement of the bytes that were approved.