fix: strip wildcard prefixes from vendored blocklist entries
All checks were successful
check / check (push) Successful in 13s
All checks were successful
check / check (push) Successful in 13s
The MetaMask blocklist contains 2 entries with '*.' wildcard prefixes (e.g. *.coinbase-563513.com). These were stored literally and never matched because hostnameVariants() doesn't generate '*.' prefixed strings. Fix: normalizeDomain() strips the '*.' prefix at load time and during delta computation. The subdomain matching in hostnameVariants() already handles child domains correctly. Found during review.
This commit is contained in:
@@ -69,8 +69,6 @@
|
||||
"web3modal.org"
|
||||
],
|
||||
"blacklist": [
|
||||
"*.chrom-coinbse-extenson.pages.dev",
|
||||
"*.coinbase-563513.com",
|
||||
"0-0.coinbase-com.info",
|
||||
"0-coinbase.com",
|
||||
"0-cz.com",
|
||||
|
||||
@@ -33,6 +33,19 @@ let lastFetchTime = 0;
|
||||
let fetchPromise = null;
|
||||
let persistedDeltaLoaded = false;
|
||||
|
||||
/**
|
||||
* Normalize a domain entry: lowercase and strip wildcard prefix ("*.").
|
||||
* Wildcard domains like "*.evil.com" become "evil.com" — our subdomain
|
||||
* matching in hostnameVariants() already covers child domains.
|
||||
*
|
||||
* @param {string} domain
|
||||
* @returns {string}
|
||||
*/
|
||||
function normalizeDomain(domain) {
|
||||
const d = domain.toLowerCase();
|
||||
return d.startsWith("*.") ? d.slice(2) : d;
|
||||
}
|
||||
|
||||
/**
|
||||
* Binary search on a sorted string array.
|
||||
*
|
||||
@@ -197,7 +210,7 @@ async function updatePhishingList() {
|
||||
// Compute blacklist delta: remote items not in vendored baseline
|
||||
const newDeltaBl = new Set();
|
||||
for (const domain of config.blacklist || []) {
|
||||
const d = domain.toLowerCase();
|
||||
const d = normalizeDomain(domain);
|
||||
if (!binarySearch(vendoredBlacklist, d)) {
|
||||
newDeltaBl.add(d);
|
||||
}
|
||||
@@ -206,7 +219,7 @@ async function updatePhishingList() {
|
||||
// Compute whitelist delta: remote items not in vendored whitelist
|
||||
const newDeltaWl = new Set();
|
||||
for (const domain of config.whitelist || []) {
|
||||
const d = domain.toLowerCase();
|
||||
const d = normalizeDomain(domain);
|
||||
if (!vendoredWhitelist.has(d)) {
|
||||
newDeltaWl.add(d);
|
||||
}
|
||||
@@ -236,12 +249,8 @@ async function updatePhishingList() {
|
||||
function loadConfig(config) {
|
||||
// For tests: treat the entire config as delta (overlaid on vendored).
|
||||
// Clear existing delta first.
|
||||
deltaBlacklistSet = new Set(
|
||||
(config.blacklist || []).map((d) => d.toLowerCase()),
|
||||
);
|
||||
deltaWhitelistSet = new Set(
|
||||
(config.whitelist || []).map((d) => d.toLowerCase()),
|
||||
);
|
||||
deltaBlacklistSet = new Set((config.blacklist || []).map(normalizeDomain));
|
||||
deltaWhitelistSet = new Set((config.whitelist || []).map(normalizeDomain));
|
||||
lastFetchTime = Date.now();
|
||||
persistedDeltaLoaded = true;
|
||||
}
|
||||
@@ -283,5 +292,6 @@ module.exports = {
|
||||
getDeltaSize,
|
||||
hostnameVariants,
|
||||
binarySearch,
|
||||
normalizeDomain,
|
||||
_reset,
|
||||
};
|
||||
|
||||
@@ -5,6 +5,7 @@ const {
|
||||
getDeltaSize,
|
||||
hostnameVariants,
|
||||
binarySearch,
|
||||
normalizeDomain,
|
||||
_reset,
|
||||
} = require("../src/shared/phishingDomains");
|
||||
|
||||
@@ -67,6 +68,35 @@ describe("phishingDomains", () => {
|
||||
});
|
||||
});
|
||||
|
||||
describe("normalizeDomain", () => {
|
||||
test("strips *. wildcard prefix", () => {
|
||||
expect(normalizeDomain("*.evil.com")).toBe("evil.com");
|
||||
expect(normalizeDomain("*.sub.evil.com")).toBe("sub.evil.com");
|
||||
});
|
||||
|
||||
test("lowercases domains", () => {
|
||||
expect(normalizeDomain("Evil.COM")).toBe("evil.com");
|
||||
expect(normalizeDomain("*.Evil.COM")).toBe("evil.com");
|
||||
});
|
||||
|
||||
test("passes through normal domains unchanged", () => {
|
||||
expect(normalizeDomain("example.com")).toBe("example.com");
|
||||
});
|
||||
});
|
||||
|
||||
describe("wildcard domain handling", () => {
|
||||
test("wildcard blacklist entries match via loadConfig", () => {
|
||||
loadConfig({
|
||||
blacklist: ["*.scam-site.com", "normal-scam.com"],
|
||||
whitelist: [],
|
||||
});
|
||||
// *.scam-site.com is normalized to scam-site.com
|
||||
expect(isPhishingDomain("scam-site.com")).toBe(true);
|
||||
expect(isPhishingDomain("sub.scam-site.com")).toBe(true);
|
||||
expect(isPhishingDomain("normal-scam.com")).toBe(true);
|
||||
});
|
||||
});
|
||||
|
||||
describe("vendored baseline detection", () => {
|
||||
// These tests verify that the vendored phishing-domains.json
|
||||
// is loaded and searchable without any delta loaded.
|
||||
|
||||
Reference in New Issue
Block a user