feat: vendor and censor the phishing blocklist at build time (closes #219)
This commit was merged in pull request #301.
This commit is contained in:
@@ -9,13 +9,12 @@
|
||||
//
|
||||
// Service-worker coverage is not free: ctx.route() only sees worker
|
||||
// traffic when PW_EXPERIMENTAL_SERVICE_WORKER_NETWORK_EVENTS=1 is set in
|
||||
// the environment, which script/test-e2e does. Without it the phishing
|
||||
// blocklist fetch that src/background/index.js issues at worker startup
|
||||
// silently reaches raw.githubusercontent.com on the open internet, and
|
||||
// src/shared/phishingDomains.js swallows the failure so nothing surfaces
|
||||
// it. That is not left to trust: waitForServiceWorkerTraffic() below
|
||||
// backs the launch-time canary in harness.js, which fails the entire
|
||||
// suite if worker requests stop being visible here.
|
||||
// the environment, which script/test-e2e does. Without it every fetch the
|
||||
// MV3 background worker makes — the JSON-RPC calls behind every approval
|
||||
// in this suite among them — goes to the real internet unobserved. That is
|
||||
// not left to trust: waitForServiceWorkerTraffic() below backs the
|
||||
// launch-time canary in harness.js, which fails the entire suite if worker
|
||||
// requests stop being visible here.
|
||||
//
|
||||
// Anything not explicitly stubbed here is aborted AND reported to the
|
||||
// error collector, so a newly added outbound call shows up as a test
|
||||
@@ -103,6 +102,22 @@ function word(value) {
|
||||
const DAPP_ORIGIN = "https://dapp.e2e.test";
|
||||
const DAPP_URL = DAPP_ORIGIN + "/";
|
||||
|
||||
// The same page, served from a hostname that is on the vendored phishing
|
||||
// blocklist, so the phishing warning can be driven end to end against the real
|
||||
// list rather than a stub of it. It is a live entry at the pinned upstream
|
||||
// commit; upstream prunes, so a re-vendoring run that retires it turns the
|
||||
// phishing test red, and the fix is a current entry, not a weaker assertion.
|
||||
const PHISHING_DAPP_ORIGIN = "https://myetheywallet.com";
|
||||
const PHISHING_DAPP_URL = PHISHING_DAPP_ORIGIN + "/";
|
||||
|
||||
// A request the harness asks the background service worker to make, purely so
|
||||
// that worker interception can be proved before any test runs. Nothing in the
|
||||
// extension fetches at startup any more — the blocklist is vendored at build
|
||||
// time — so the canary in harness.js has no product traffic to anchor on and
|
||||
// generates its own. See assertWorkerTrafficIntercepted().
|
||||
const WORKER_PROBE_ORIGIN = "https://worker-probe.e2e.test";
|
||||
const WORKER_PROBE_URL = WORKER_PROBE_ORIGIN + "/canary";
|
||||
|
||||
// Requests are parked rather than awaited. An approval prompt only exists
|
||||
// while its call is in flight, so a test that awaited the promise could
|
||||
// never drive the popup that has to settle it; start() files the promise
|
||||
@@ -555,10 +570,9 @@ async function installNetworkStubs(ctx, opts) {
|
||||
// E2E_TRACE_NETWORK=1 prints every request that reaches this handler,
|
||||
// tagged [sw] when it originated in the background service worker.
|
||||
// It exists so the isolation claim above can be re-checked by anyone
|
||||
// in one command, without editing files: the phishing blocklist fetch
|
||||
// showing up with an [sw] tag is the proof that the worker really is
|
||||
// intercepted and that the raw.githubusercontent.com stub below is
|
||||
// live code rather than decoration.
|
||||
// in one command, without editing files: the canary probe and then
|
||||
// every JSON-RPC call behind an approval showing up with an [sw] tag
|
||||
// is the proof that the worker really is intercepted.
|
||||
const trace = traceEnabled(process.env.E2E_TRACE_NETWORK);
|
||||
|
||||
// Regex rather than a glob so chrome-extension:// resource loads are
|
||||
@@ -589,7 +603,11 @@ async function installNetworkStubs(ctx, opts) {
|
||||
// trips run against a real http(s) origin — which is what makes the
|
||||
// shipped content scripts inject at all — without any remote origin
|
||||
// being involved.
|
||||
if (url.origin === DAPP_ORIGIN && p === "/") {
|
||||
if (
|
||||
(url.origin === DAPP_ORIGIN ||
|
||||
url.origin === PHISHING_DAPP_ORIGIN) &&
|
||||
p === "/"
|
||||
) {
|
||||
return route.fulfill({
|
||||
status: 200,
|
||||
contentType: "text/html; charset=utf-8",
|
||||
@@ -635,18 +653,10 @@ async function installNetworkStubs(ctx, opts) {
|
||||
return jsonResponse(route, { Data: {} });
|
||||
}
|
||||
|
||||
// MetaMask phishing blocklist
|
||||
if (
|
||||
url.hostname === "raw.githubusercontent.com" ||
|
||||
p.endsWith("/eth-phishing-detect/main/src/config.json")
|
||||
) {
|
||||
return jsonResponse(route, {
|
||||
version: 2,
|
||||
tolerance: 2,
|
||||
fuzzylist: [],
|
||||
whitelist: [],
|
||||
blacklist: [],
|
||||
});
|
||||
// The interception canary's own request. Answered with nothing: what
|
||||
// is being observed is that it arrived here at all.
|
||||
if (url.href === WORKER_PROBE_URL) {
|
||||
return route.fulfill({ status: 204, body: "" });
|
||||
}
|
||||
|
||||
// Best-effort Etherscan address labels: served as an empty page.
|
||||
@@ -667,12 +677,12 @@ async function installNetworkStubs(ctx, opts) {
|
||||
* Resolve with the first service-worker-originated request this
|
||||
* handler saw, or null if none arrives within `ms`.
|
||||
*
|
||||
* The background worker fetches the phishing blocklist at
|
||||
* startup, unconditionally, within about a second of the context
|
||||
* coming up — so under working interception this resolves almost
|
||||
* immediately. Nothing arriving means worker traffic is bypassing
|
||||
* the handler entirely and going to the real internet, which the
|
||||
* caller turns into a hard failure of the whole suite.
|
||||
* The caller asks the worker for one request of its own (see
|
||||
* WORKER_PROBE_URL) and then waits here, so under working
|
||||
* interception this resolves almost immediately. Nothing arriving
|
||||
* means worker traffic is bypassing the handler entirely and going
|
||||
* to the real internet, which the caller turns into a hard failure
|
||||
* of the whole suite.
|
||||
*/
|
||||
waitForServiceWorkerTraffic(ms) {
|
||||
if (firstWorkerRequest) return Promise.resolve(firstWorkerRequest);
|
||||
@@ -696,6 +706,9 @@ module.exports = {
|
||||
DAPP_HTML,
|
||||
DAPP_ORIGIN,
|
||||
DAPP_URL,
|
||||
PHISHING_DAPP_ORIGIN,
|
||||
PHISHING_DAPP_URL,
|
||||
WORKER_PROBE_URL,
|
||||
FEE_ESTIMATE_WEI,
|
||||
FEE_RESERVE_WEI,
|
||||
STUB_COUNTERPARTY,
|
||||
|
||||
Reference in New Issue
Block a user