flashman
← All posts

Subresource integrity digest debugging

Debug a script blocked by subresource integrity by matching the attribute algorithm to a digest of the exact bytes the browser received, not a nearby file.

2026-10-15 · 6 min read · Rahul Chitturi

  • sri
  • security
  • frontend

An integrity attribute tells the browser the digest the script or stylesheet must have. If the bytes do not match, the browser does not execute the script and does not apply the stylesheet. The network request can still succeed. The failure is in the console, not in the status code.

The token is an algorithm, a hyphen, and the standard base64 of the raw digest. sha256, sha384, and sha512 are the names that matter. Hex, base64url, and a hash of a different file all fail the check.

Use the strongest algorithm in the attribute

When several tokens are present, the browser verifies the strongest algorithm it supports. A correct sha256 does not rescue a stale sha512 sitting next to it. Remove the old token or recompute every algorithm from the same bytes.

Standard base64 uses plus, slash, and padding. Base64url uses minus and underscore and often drops the padding. Pasting a base64url digest into integrity fails even when the hash bytes are right. A hex string is not a substitute: it is a different alphabet of the same digest.

  • Hash the bytes the browser will execute.
  • Hash after content-encoding is removed, not the gzip member.
  • Include a trailing newline only if the served file has one.
  • Recompute every algorithm you leave in the attribute.

Separate a bad digest from a blocked CORS response

A cross-origin script or stylesheet with integrity needs a CORS response. Set crossorigin to anonymous unless the request truly needs cookies, and confirm the server sends Access-Control-Allow-Origin for the page's origin. A missing CORS header fails the load while the digest is still correct.

Same-origin files do not need that header. An edge rewrite, a tag-manager injection, or a service worker that edits the body will change the digest after you computed it. Diff the file you hashed with the response body from the browser.

Compare text copies without inventing the token

Flashman's hash tool prints SHA-256 or SHA-512 hex of the UTF-8 text in the box. It does not print a base64 integrity token, and it does not compute SHA-384. Use it to see whether two copies of the source differ, including a trailing newline.

Do not paste that hex into the Base64 tool and expect the integrity token. The Base64 tool encodes the hex characters as text, not the raw digest bytes. Diff the two sources, then recompute the real token with a command that hashes bytes and base64-encodes the digest.

Try these tools