Why an integrity attribute needs a crossorigin attribute too

Subresource Integrity lets a page declare the exact hash a cross-origin script or stylesheet must have before a browser will run or apply it. It is easy to add the integrity attribute and stop there, assuming the tag is now protected. In most browsers, it isn't -- not without a second attribute most guides mention only in passing.

Why the browser needs permission to check at all

Reading enough about a cross-origin response to verify a hash against it is itself a CORS-gated operation, under the same Fetch spec that governs Access-Control-Allow-Origin. A plain <script src="https://cdn.example.com/lib.js"> tag does not opt into CORS mode by default -- it is what the spec calls a "no-cors" request. Adding crossorigin="anonymous" (or "use-credentials", for the rare case that needs cookies sent) is what opts the request into CORS mode, which is the mode integrity checking requires.

The two ways to get this half right and still be unprotected

Tag hasWhat actually happens
integrity, no crossoriginMost browsers silently skip the integrity check rather than enforcing it. The page source looks protected; a visitor's browser is not checking anything.
crossorigin, no integrityThe request opts into CORS mode, but there is no hash to check it against -- no protection is configured at all, just a slightly different network request.
Both, correctlyThe browser fetches the resource in CORS mode, hashes what it receives, and refuses to run or apply it if the hash does not match one of the declared values.

Check a whole page automatically

The checker on this site fetches a page you name and every cross-origin script/stylesheet tag it loads, and reports exactly which tags are missing integrity, missing crossorigin, or declare a hash that no longer matches what the CDN currently serves -- plus a standalone hash generator for fixing what it finds. The page-fetching half runs as a Node CLI, since reading another site's full HTML from browser JavaScript is itself restricted by CORS; the hash generator has no such limit, because it only hashes content you paste in.

This is evidence about one specific protection, not a full security assessment -- see the checker and its disclaimer for what it does and doesn't cover.

← Back to the checker