verify-build read its expectation from AUTISTMASK_DEBUG in its own environment and the Makefile invoked it bare, so an operator with that variable exported who ran the release target got an INSECURE debug build — every wallet it creates uses the publicly committed test phrase — verified green, exit 0. It also had no provenance: a 26-byte file containing the right marker string passed, the content script and manifest.json were never inspected, and an entire hand-written dist/ passed. --expect release|debug and --receipt PATH are now both required, with no defaults and nothing read from the environment. build.js records every file it emits with its sha256 and writes the receipt; the Makefile mktemps it outside the repo per invocation with a trap, and build.js refuses a receipt path inside dist/. Verification runs three passes in a load-bearing order — receipt shape, full dist/ walk, then per-file bytes — so an unwalkable subtree cannot make files look absent. dist/constants-bundles.txt, which was an unsigned trust root living inside the tree it vouched for, is gone. What this proves is bounded and stated as such: dist/ is byte-for-byte the output of the build.js run that just finished, within one make build invocation. It proves nothing about the honesty of the source tree or build.js, and nothing to anyone handed a dist/ from elsewhere — that is signing, #310. The standalone make verify-build target is removed because its only input would be dist/ itself, i.e. the artifact vouching for itself. Verified: make check green, test-verify-build 39 cases (was 18), test-e2e 55/55 and test-e2e-firefox 8/8 with make build running uncached inside both images. All four original bypasses now exit 1. Mutations: digests disabled fails exactly 4 cases, dropping the dist/ walk fails exactly 8, restoring the ambient fallback fails exactly 1.
98 lines
3.1 KiB
Makefile
98 lines
3.1 KiB
Makefile
.PHONY: bootstrap setup install test test-e2e test-e2e-firefox lint fmt fmt-check check check-censored docker hooks build build-debug vendor-blocklist clean dev
|
|
|
|
# Standard targets are thin shims; the implementations live in script/
|
|
# per the scripts-to-rule-them-all pattern (see the Entrypoints section
|
|
# of README.md).
|
|
|
|
bootstrap:
|
|
@script/bootstrap
|
|
|
|
setup:
|
|
@script/setup
|
|
|
|
install:
|
|
@yarn install --frozen-lockfile
|
|
|
|
test:
|
|
@script/test
|
|
|
|
# Browser end-to-end suites. Both require docker; neither is part of check.
|
|
test-e2e:
|
|
@script/test-e2e
|
|
|
|
test-e2e-firefox:
|
|
@script/test-e2e-firefox
|
|
|
|
lint:
|
|
@script/lint
|
|
|
|
fmt:
|
|
@script/fmt
|
|
|
|
fmt-check:
|
|
@script/fmt-check
|
|
|
|
check:
|
|
@script/check
|
|
|
|
# Assert that the competitor name appears nowhere but its documented
|
|
# exceptions. Part of check, and re-run against dist/ at the end of a build;
|
|
# separate target for re-running it alone.
|
|
check-censored:
|
|
@script/check-censored
|
|
|
|
docker:
|
|
@script/docker
|
|
|
|
hooks:
|
|
@script/install-precommit
|
|
|
|
# build.js writes a receipt of everything it emitted — every path, its sha256,
|
|
# and whether it is a bundle containing constants.js — and script/verify-build
|
|
# checks dist/ against that. The receipt is made here, fresh per invocation,
|
|
# outside the repo, and deleted again: a standing file inside dist/ would be
|
|
# rewritten by whoever rewrote dist/, which is what made the old check
|
|
# satisfiable by a hand-written tree.
|
|
#
|
|
# The expected mode is an explicit argument and AUTISTMASK_DEBUG is scrubbed
|
|
# from the verifier's environment. The script no longer reads it at all; env -u
|
|
# is here so that stays true of anything it calls. It is deliberately NOT
|
|
# scrubbed from the build itself: with AUTISTMASK_DEBUG=1 exported, this target
|
|
# compiles a debug bundle and then fails on it, loudly, rather than quietly
|
|
# handing back something other than the release build that was asked for.
|
|
build:
|
|
@echo "Building extension..."
|
|
@set -eu; \
|
|
receipt="$$(mktemp "$${TMPDIR:-/tmp}/autistmask-build-receipt.XXXXXX")"; \
|
|
trap 'rm -f "$$receipt"' EXIT INT TERM; \
|
|
AUTISTMASK_BUILD_RECEIPT="$$receipt" yarn run build 2>&1; \
|
|
env -u AUTISTMASK_DEBUG script/verify-build --expect release \
|
|
--receipt "$$receipt"
|
|
@script/check-censored --require-dist
|
|
|
|
# Development-only build: enables the red DEBUG / INSECURE banner and makes
|
|
# the hardcoded test recovery phrase the output of wallet creation. Never
|
|
# distribute the artifacts this produces.
|
|
build-debug:
|
|
@echo "Building extension (DEBUG)..."
|
|
@set -eu; \
|
|
receipt="$$(mktemp "$${TMPDIR:-/tmp}/autistmask-build-receipt.XXXXXX")"; \
|
|
trap 'rm -f "$$receipt"' EXIT INT TERM; \
|
|
AUTISTMASK_DEBUG=1 AUTISTMASK_BUILD_RECEIPT="$$receipt" yarn run build 2>&1; \
|
|
env -u AUTISTMASK_DEBUG script/verify-build --expect debug \
|
|
--receipt "$$receipt"
|
|
@script/check-censored --require-dist
|
|
|
|
# Refresh src/shared/phishingBlocklist.json from its hash-pinned upstream.
|
|
# Run deliberately, land the diff: the extension does no runtime fetching, so
|
|
# the shipped list is as fresh as the last vendoring run that was released.
|
|
vendor-blocklist:
|
|
@script/vendor-blocklist
|
|
|
|
clean:
|
|
@rm -rf dist/
|
|
|
|
dev:
|
|
@echo "Building in watch mode..."
|
|
@yarn run build --watch 2>&1
|