Skip to content

Polyfill crypto.subtle.digest() (SHA-1/SHA-256) for non-secure contexts #393

Open

Description

@benoit74

Context

Follow-up to #391 (openzim/warc2zim#327). After polyfilling crypto.randomUUID(), a user testing the same ZIM over a non-localhost, plain-HTTP host (Tailscale hostname) still saw all of MDN's live-sample iframes stuck at src="about:blank", with no visible JS error at all.

Root cause

crypto.subtle (the SubtleCrypto interface) is, like randomUUID, restricted to secure contexts (HTTPS, or localhost) — confirmed via typeof crypto.subtle === "undefined" on the affected page. Unlike randomUUID, code calling into it here fails silently (the async function computing the live-sample's content hash just never resolves/throws visibly), which is why nothing showed in the console beyond the (now-fixed) randomUUID error.

Two call sites were found in the test ZIM:

  • MDN's own bundle (developer.mozilla.org/static/client/4098.*.js) uses it to build the live-sample id: crypto.subtle.digest("SHA-256", <deflate-compressed code>), truncated to the first 20 bytes.
  • Our own vendored wombat.js already optionally uses crypto.subtle.digest("SHA-1", ...) to compute a response ETag, already wrapped in a try/catch that degrades gracefully when it's unavailable.

Suggested fix

Unlike randomUUID, there's no single built-in primitive to delegate to — digest() needs an actual hash implementation. Add a small, pure-JS, dependency-free digest(algorithm, data) polyfill supporting SHA-1 and SHA-256 (the two algorithms actually observed in use), installed on crypto.subtle the same way the randomUUID polyfill is installed on crypto (feature-detected, only when crypto.subtle is missing), returning a Promise<ArrayBuffer> matching the native SubtleCrypto.digest() contract.

I'll attempt a local patch (cross-validated against Node's native crypto module for correctness across many inputs, including block-boundary edge cases) and open a PR against this issue — likely extending PR #392 (#392), since it's the same wombatSetup.js secure-context-polyfill mechanism.

Metadata

Metadata

Assignees

Labels

No labels
No labels

Type

Projects

No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions