CentralCSP
Other

Subresource Integrity

SRI is the integrity attribute that makes the browser hash a fetched script or stylesheet and refuse it on mismatch, defending against a tampered CDN.

Last update:

Subresource Integrity (SRI) is the integrity attribute you add to a <script> or <link rel="stylesheet"> that loads code from another host. The browser hashes the bytes it fetches and compares them to the hash you wrote. If they do not match, the browser refuses to run or apply the resource and treats it as a network error. It defends against one specific threat: a third-party host or content delivery network (CDN) that serves you tampered or compromised code.

One directive is dead, one is the modern way

The old CSP require-sri-for directive never shipped to a stable browser and is abandoned. Do not use it. To require SRI today you use the Integrity-Policy header, which is recent and not yet Baseline. See Browser support.

A minimal example

You add the hash, the resource's host, and (for a cross-origin host) the crossorigin attribute. The browser does the rest.

<script
  src="https://cdn.example.com/library.js"
  integrity="sha384-oqVuAfXRKap7fdgcCY5uykM6+R9GqQ8K/uxy9rx7HNQlGYl1kPzQho1wx4JwY8wC"
  crossorigin="anonymous"
></script>

If the file at that URL changes by even one byte, the hash no longer matches and the browser drops the script. That is the point: you pin an exact, known-good version.

Syntax and algorithms

An integrity value is an algorithm prefix, a dash, and a base64-encoded digest of the response bytes.

<link
  rel="stylesheet"
  href="https://cdn.example.com/app.css"
  integrity="sha384-VuArbKap7CY5uykM6oqf+R9GqQ8Kux9rx7HNQlGYl1kPzQho1wx4JwY8wCdgcRRap"
  crossorigin="anonymous"
/>

Three hash functions are allowed: sha256, sha384, and sha512. You can list several space-separated tokens, and how the browser treats them depends on whether the algorithms differ:

  • Different algorithms (strongest wins). If you list a sha256 and a sha512 token, the browser picks the strongest algorithm present and validates against only that one. Listing a weaker hash next to a stronger one does not weaken the check.
  • Same algorithm (any match). If you list two sha384 tokens, the resource is accepted when it matches either one. This is how you allow more than one acceptable payload, for example during a rollover between two file versions.

The digest is the hash of the raw response body, base64-encoded, not a hash of the URL or the file name.

How to generate the hash

The integrity value is the base64-encoded digest of the raw response bytes, prefixed with the algorithm (sha384-). Generate it with our SRI generator, which produces the full integrity value from a URL or a file and returns the sha256, sha384, and sha512 variants to paste into the attribute.

The crossorigin requirement

SRI relies on Cross-Origin Resource Sharing (CORS). The browser cannot read the bytes of an opaque cross-origin response, so it cannot verify a hash against them.

For a cross-origin resource, the integrity attribute does nothing on its own. You must also set crossorigin="anonymous" (or use-credentials), and the serving host must return an Access-Control-Allow-Origin header that permits your origin. Miss either piece and the resource always fails to load.

Access-Control-Allow-Origin: *

For a same-origin resource the browser can already read the bytes, so no crossorigin attribute is needed.

What SRI covers and what it does not

SRI applies to a fixed set of resource types:

  • <script> elements.
  • <link rel="stylesheet">.
  • <link rel="preload"> and <link rel="modulepreload">.
  • The HTTP Link header integrity parameter, the header-based equivalent of a preload.
  • Dynamically imported ES modules, through the integrity field of an import map, supported across current Chrome, Firefox, and Safari.

It does not cover images, audio, video, <iframe>, or <object> today.

The cost is maintenance. SRI needs a pinned, immutable file. A resource that mutates, a CDN that auto-minifies, or a URL that always points at the "latest" build, breaks the hash on every change. You have to regenerate the hash whenever the file legitimately changes, which is why teams pin a versioned URL and update both the URL and the hash together. CentralCSP's script inventory detects the third-party scripts on your pages and flags when one of them changes, which is the signal that an SRI hash needs updating or that something shifted unexpectedly.

SRI hashes vs CSP hash sources

These look identical and mean different things, so it is worth keeping them apart.

SRI hashCSP hash source
Lives onThe integrity attribute of an elementA script-src / style-src source in the policy
HashesThe bytes of an external resource fetched by URLThe text content of an inline element
Prefixsha256- / sha384- / sha512-sha256- / sha384- / sha512-

Both use the same sha256-, sha384-, and sha512- base64 prefix, but the input differs: SRI hashes the response body of a resource loaded from a URL, while a CSP hash source hashes the inline content of an element so the policy can allow it. The same string in the wrong place will not do what you expect.

Requiring SRI with Integrity-Policy

SRI is opt-in per element. Nothing stops a developer from adding a new external script without an integrity attribute. The Integrity-Policy header closes that gap: it tells the browser to block any resource of a given destination that loads without valid integrity metadata.

Integrity-Policy: blocked-destinations=(script), endpoints=(integrity-endpoint)

You wire the named endpoint through a Reporting-Endpoints header:

Reporting-Endpoints: integrity-endpoint="https://<Endpoint-ID>.report.centralcsp.com"

A script without valid integrity is then blocked, and the browser emits an integrity-violation report to that endpoint. A report-only variant, Integrity-Policy-Report-Only, reports the same violations without blocking, so you can measure coverage before enforcing.

SRI and CSP

SRI and CSP are orthogonal controls that you run together. CSP decides whether a script is allowed to run at all and how trust propagates between scripts. SRI verifies that the bytes of an allowed script are the exact ones you expected. A script can pass CSP and still be tampered with; SRI is what catches that.

The old way to combine them was the CSP require-sri-for directive, which would have forced integrity metadata on scripts or styles. It never shipped to a stable browser and is abandoned, so do not reach for it. Its role is now filled by the Integrity-Policy header above.

Build tooling

Generating and maintaining hashes by hand does not scale, so let the bundler emit them:

Browser support

The core integrity attribute on scripts and stylesheets is widely supported across modern browsers. The require-sri-for CSP directive never shipped and is dead. The Integrity-Policy header is recent: script-destination enforcement ships in Chrome, Firefox, and Safari, but it is not yet Baseline.

See also

Sources

On this page