From e08b4090436f1bb79b966d8a99b8f28849619321 Mon Sep 17 00:00:00 2001 From: user Date: Sun, 1 Mar 2026 05:03:39 -0800 Subject: [PATCH] feat: add Etherscan label scraping and MetaMask phishing domain blocklist - Add etherscanLabels module: scrapes Etherscan address pages for phishing/scam labels (Fake_Phishing*, Exploiter, scam warnings). Integrated as best-effort async check in addressWarnings. - Add phishingDomains module: fetches MetaMask's eth-phishing-detect blocklist (~231K domains) at runtime, caches in memory, refreshes every 24h. Checks hostnames with subdomain matching and whitelist overrides. - Integrate domain phishing checks into all approval flows: connection requests, transaction approvals, and signature requests show a prominent red warning banner when the requesting site is on the MetaMask blocklist. - Add unit tests for both modules (12 tests for etherscanLabels parsing, 15 tests for phishingDomains matching). Closes #114 --- src/background/index.js | 10 ++ src/popup/index.html | 42 +++++++++ src/popup/views/approval.js | 30 ++++++ src/shared/addressWarnings.js | 11 +++ src/shared/etherscanLabels.js | 102 +++++++++++++++++++++ src/shared/phishingDomains.js | 133 +++++++++++++++++++++++++++ tests/etherscanLabels.test.js | 100 ++++++++++++++++++++ tests/phishingDomains.test.js | 166 ++++++++++++++++++++++++++++++++++ 8 files changed, 594 insertions(+) create mode 100644 src/shared/etherscanLabels.js create mode 100644 src/shared/phishingDomains.js create mode 100644 tests/etherscanLabels.test.js create mode 100644 tests/phishingDomains.test.js diff --git a/src/background/index.js b/src/background/index.js index 1060fcf..7b4ea8a 100644 --- a/src/background/index.js +++ b/src/background/index.js @@ -12,6 +12,10 @@ const { refreshBalances, getProvider } = require("../shared/balances"); const { debugFetch } = require("../shared/log"); const { decryptWithPassword } = require("../shared/vault"); const { getSignerForAddress } = require("../shared/wallet"); +const { + isPhishingDomain, + updatePhishingList, +} = require("../shared/phishingDomains"); const storageApi = typeof browser !== "undefined" @@ -571,6 +575,10 @@ async function backgroundRefresh() { setInterval(backgroundRefresh, BACKGROUND_REFRESH_INTERVAL); +// Fetch the MetaMask eth-phishing-detect domain blocklist on startup. +// Refreshes every 24 hours automatically. +updatePhishingList(); + // When approval window is closed without a response, treat as rejection if (windowsApi && windowsApi.onRemoved) { windowsApi.onRemoved.addListener((windowId) => { @@ -643,6 +651,8 @@ runtime.onMessage.addListener((msg, sender, sendResponse) => { resp.type = "sign"; resp.signParams = approval.signParams; } + // Flag if the requesting domain is on the phishing blocklist. + resp.isPhishingDomain = isPhishingDomain(approval.hostname); sendResponse(resp); } else { sendResponse(null); diff --git a/src/popup/index.html b/src/popup/index.html index f53df66..cf99aad 100644 --- a/src/popup/index.html +++ b/src/popup/index.html @@ -1176,6 +1176,20 @@