Vendor wasm-feature-detect instead of loading it unpinned from unpkg (scrutineer #2520) - #2404
Draft
JasonGross wants to merge 1 commit into
Draft
Vendor wasm-feature-detect instead of loading it unpinned from unpkg (scrutineer #2520)#2404JasonGross wants to merge 1 commit into
JasonGross wants to merge 1 commit into
Conversation
fiat-html/fiat-crypto.html loaded https://unpkg.com/wasm-feature-detect/dist/umd/index.js with no version, no `integrity` and no `crossorigin` attribute. The published page at https://mit-plv.github.io/fiat-crypto/ (deployed verbatim from fiat-html/) therefore executed whatever the CDN returned for that URL, with full access to the page origin, even though the script is only used by disable-wasm-option.js for a cosmetic capability probe (scrutineer finding #2520, CWE-829). Vendor the UMD build of wasm-feature-detect@1.9.0 (the version the unversioned unpkg URL currently redirects to) under fiat-html/vendor/wasm-feature-detect/, byte-for-byte identical to dist/umd/index.js from the npm tarball, together with its Apache-2.0 LICENSE and a README recording the version, source URL, registry integrity hash and SHA-384 of the file, plus update instructions. Load it from the local path so the page no longer runs any third-party-hosted script. The deploy workflows publish the whole fiat-html/ folder from a checkout, so the vendored files ship with the page. Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_016Rbn2gww3MGhvrh52fNjpD
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Fixes scrutineer finding #2520 (CWE-829, Low).
The bug
fiat-html/fiat-crypto.html(line 251) loadedhttps://unpkg.com/wasm-feature-detect/dist/umd/index.jswith no version in the URL, nointegrityattribute and nocrossoriginattribute. The page is deployed verbatim fromfiat-html/to https://mit-plv.github.io/fiat-crypto/ (bydeploy-html-fast.ymland thedeploy-js-wasm-of-ocamljob ofcoq-docker.yml), so every visitor executed whatever unpkg returned for that URL, as a classic script with full access to the page origin (localStoragesynthesis cache, generated output in the DOM). The only consumer isdisable-wasm-option.js, which callswasmFeatureDetect.tailCall()/gc()/exceptions()to decide whether to enable the WASM checkbox.The fix
Vendor the UMD build of
wasm-feature-detect@1.9.0(latest release, published 2026-08-11, and the version the unversioned unpkg URL currently 302-redirects to, so the page's behaviour is unchanged) intofiat-html/vendor/wasm-feature-detect/:wasm-feature-detect-1.9.0.umd.js: byte-for-bytedist/umd/index.jsfrom the npm tarball (not edited, so it can be re-verified against upstream by hash).LICENSE: the package's Apache-2.0 licence text (the package is Apache-2.0, not MIT).README.md: version, upstream URLs, the registrysha512integrity of the tarball, the SRIsha384of the vendored file, and update instructions.fiat-crypto.htmlnow loadsvendor/wasm-feature-detect/wasm-feature-detect-1.9.0.umd.jswith an HTML comment recording version, licence and source URL. The page no longer runs any third-party-hosted script.Alternatives considered: pinning the version in the unpkg URL and adding
integrity="sha384-..." crossorigin="anonymous"would also close the finding, but keeps a runtime dependency on a CDN (an outage or acrossoriginmisconfiguration would silently disable the WASM option). Vendoring a 3.6 KB file is simpler and makes the deployed page self-contained. No other unpinned third-party script exists:grep -rnE 'https?://[^" ]*\.(js|mjs|css)|unpkg|jsdelivr|cdnjs' fiat-html .github/workflowsonly matched this line (thedl-cdn.alpinelinux.orghits are apk repositories, not scripts).Verification
curl https://registry.npmjs.org/wasm-feature-detect:dist-tags.latest = 1.9.0,license = Apache-2.0, integritysha512-zonE+xlIIYtxPy++L24ow0hAD8CICb4+FgPyROd3buyXIqsJvUEDkBgfCCoXOd1Hu3DUr0GOfnPIdcGV+YpNaA==.openssl dgst -sha512of it matches the registry integrity hash.cmp package/dist/umd/index.js <(curl https://unpkg.com/wasm-feature-detect@1.9.0/dist/umd/index.js): identical;cmpof the vendored file against that unpkg copy: identical.curl -I https://unpkg.com/wasm-feature-detect/dist/umd/index.jsis a 302 to/wasm-feature-detect@1.9.0/dist/umd/index.js, i.e. the deployed page was already getting exactly these bytes.node --check fiat-html/vendor/wasm-feature-detect/wasm-feature-detect-1.9.0.umd.js: OK (node v22.23.1). Loading it in avmcontext defines globalwasmFeatureDetectwith 23 probes;tailCall,gc,exceptionsare functions and each resolves totrueunder node.fiat-html/withpython3 -m http.serverand fetchedindex.html(symlink tofiat-crypto.html),fiat-crypto.html,vendor/wasm-feature-detect/wasm-feature-detect-1.9.0.umd.jsandvendor/wasm-feature-detect/LICENSE: all 200, so the relative path resolves from the page.make -f Makefile.js-html fiat-html/version.js(the only Makefile target the deploy workflows run onfiat-html/) still works;git check-ignore fiat-html/vendor/...confirms nothing underfiat-html/vendor/is gitignored. Both deploy jobs check out the repo before publishing the wholefiat-html/folder, anddeploy-html-fast.ymlrestores tracked files withgit checkout HEAD --, so the vendored files are published.Not verified
disable-wasm-option.jsstill enables/disables the checkbox correctly was done only by running the vendored script under node. The dry-run deploy in CI (deploy-js-wasm-of-ocamlon PRs) should confirm the folder layout.🤖 Generated with Claude Code
https://claude.ai/code/session_016Rbn2gww3MGhvrh52fNjpD