#!/bin/sh # script/vendor-blocklist: refresh the vendored phishing blocklist at # src/shared/phishingBlocklist.json from its upstream source. Our own extension # to scripts-to-rule-them-all. # # This is build-time repo tooling and is not shipped. It is the one place in # this repo that names the upstream project, because a source reference that # does not say what the source is cannot be verified by anyone; the artifact it # writes carries no names at all (see src/shared/domainHash.js). # script/check-censored reads the name back out of this file rather than # repeating it, so it stays defined exactly once. # # Run it deliberately, not on every build: the output is committed, and the # extension does no runtime fetching, so the shipped list is exactly as fresh as # the last time someone ran this and landed the result. Re-run it, land the # diff, cut a release; that is the whole refresh path. # # Pinned by content hash, twice over, as REPO_POLICIES.md requires. The commit # below is an immutable ref — the upstream default branch moves several times a # day and cannot be pinned — and UPSTREAM_SHA256 is the sha256 of the bytes that # commit serves. A mismatch is a hard failure: a vendoring step that accepts # whatever it is handed is a supply-chain hole, and this one feeds a security # warning shown to users. # # To move the pin: pick the new commit, run this with the new UPSTREAM_COMMIT # and an UPSTREAM_SHA256 you have not yet updated, and it will print the hash it # actually got. Verify that hash against the source independently before # recording it. Never copy the "actual" line in on trust. set -eu ROOT="$(cd "$(dirname "$0")/.." && pwd -P)" # Upstream, pinned 2026-08-17. UPSTREAM_ORG="MetaMask" UPSTREAM_REPO="eth-phishing-detect" UPSTREAM_COMMIT="6dddf74a87da3e1a0841f7ae0d1cb31aaf2c05db" UPSTREAM_FILE="src/config.json" UPSTREAM_SHA256="166d5b3504e8f4ed52eae37d3dd20c1a56efa0502bfb3dc957044ff8b5f1283f" OUTPUT="src/shared/phishingBlocklist.json" WORK="" cleanup() { [ -z "$WORK" ] || rm -rf "$WORK" } trap cleanup EXIT INT TERM fail() { echo "vendor-blocklist: $*" >&2 exit 1 } sha256_of() { if command -v sha256sum >/dev/null 2>&1; then sha256sum "$1" | cut -d' ' -f1 elif command -v shasum >/dev/null 2>&1; then shasum -a 256 "$1" | cut -d' ' -f1 else fail "neither sha256sum nor shasum is available, so the fetched source cannot be verified. Refusing to vendor unverified content." fi } main() { cd "$ROOT" command -v curl >/dev/null 2>&1 || fail "curl is required to fetch the upstream list" command -v node >/dev/null 2>&1 || fail "node is required to build the artifact; run script/bootstrap" WORK="$(mktemp -d "${TMPDIR:-/tmp}/autistmask-vendor-blocklist.XXXXXX")" || fail "could not create a working directory" url="https://raw.githubusercontent.com/$UPSTREAM_ORG/$UPSTREAM_REPO/$UPSTREAM_COMMIT/$UPSTREAM_FILE" echo "Fetching $url" curl -fsSL --proto '=https' --tlsv1.2 -o "$WORK/source.json" "$url" || fail "the fetch failed, so nothing was vendored" actual="$(sha256_of "$WORK/source.json")" if [ "$actual" != "$UPSTREAM_SHA256" ]; then fail "sha256 mismatch on the fetched source. expected: $UPSTREAM_SHA256 actual: $actual The pinned commit is immutable, so the same commit serving different bytes means the content was substituted somewhere between upstream and here. Nothing was written. Do not update the expectation to match unless you have verified the new bytes independently." fi echo "Verified sha256 $actual" node script/lib/build-blocklist.js "$WORK/source.json" "$WORK/out.json" || fail "the transform failed, so nothing was written" if [ -f "$OUTPUT" ] && cmp -s "$WORK/out.json" "$OUTPUT"; then echo "vendor-blocklist: $OUTPUT is already up to date" return 0 fi cp "$WORK/out.json" "$OUTPUT" echo "vendor-blocklist: wrote $OUTPUT (sha256 $(sha256_of "$OUTPUT"))" } main "$@"