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.
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.
| Tag has | What actually happens |
|---|---|
integrity, no crossorigin | Most 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 integrity | The 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, correctly | The 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. |
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.