Skip to content

[suggestion] Remove duplicate root domain entries from config.json array #240528

@dubstard

Description

@dubstard
Image

Currently the array "blacklist": which starts on line 71 in the file config.json in contains some dupes which could be removed, with no IRL effect on the block functionality.
the worst offenders are fullsailevents.com, airdropsalert.* and airdropsalerts.* which exist countless times with no gain from this

Rationale
Save space, keep same blocking. small maintenance tidy up

For stuff like wuaze.com (trancod) or platfoms like wiz wix and pages dev or webflow - obviously decuplication and stripping to root does not apply

Redundant lines which can be likely removed ~38K

Examples:

ROOT: fullsailevents.com
Subdomains: 9857
Saved lines: 9856
Examples:
 - 765ce-2026.mario-s-event-organization.fullsailevents.com
 - 98765ce-2026.mario-s-event-organization.fullsailevents.com
 - adcbaupdate.yxwvutsnmlkjihgfedsummer-conference-2026.mario-s-event-organization.fullsailevents.com

ROOT: 1925273-coinbase.com
Subdomains: 309
Saved lines: 308
Examples:
 - 0075164f-9251-48c3-97f3-146abf12afe6-access.1925273-coinbase.com
 - 0075164f-9251-48c3-97f3-146abf12afe6-admin.1925273-coinbase.com
 - 0075164f-9251-48c3-97f3-146abf12afe6-administrator.1925273-coinbase.com

ROOT: opensea-gifts.com
Subdomains: 290
Saved lines: 289
Examples:
 - 001412.opensea-gifts.com
 - 003602.opensea-gifts.com
 - 006975.opensea-gifts.com

ROOT: airdropsalert.life
Subdomains: 151
Saved lines: 150
Examples:
 - 0glabs.airdropsalert.life
 - 1inch.airdropsalert.life
 - 2049.airdropsalert.life


ROOT: coinbase-com.info
Subdomains: 123
Saved lines: 122
Examples:
 - 0-0.coinbase-com.info
 - 0dc-dozeo.coinbase-com.info
 - 1.new.sas-cas-0072.sasg.coinbase-com.info


ROOT: coinbase-farmers.top
Subdomains: 122
Saved lines: 121
Examples:
 - 014w8.coinbase-farmers.top
 - 0afmf.coinbase-farmers.top

ROOT: coinbase-farmworld.top
Subdomains: 107
Saved lines: 106
Examples:
 - 0afmf.coinbase-farmworld.top
 - 0u12d.coinbase-farmworld.top
 - 16bz5.coinbase-farmworld.top


ROOT: stakingsreward.life
Subdomains: 96
Saved lines: 95
Examples:
 - 0g.stakingsreward.life
 - 1inch.stakingsreward.life
 - 2z.stakingsreward.life

ROOT: coinbase-farmworld.xyz
Subdomains: 94
Saved lines: 93
Examples:
 - 014w8.coinbase-farmworld.xyz
 - 16bz5.coinbase-farmworld.xyz
 - 1846m.coinbase-farmworld.xyz

ROOT: stakingsreward.art
Subdomains: 94
Saved lines: 93
Examples:
 - 0g.stakingsreward.art
 - 1inch.stakingsreward.art
 - 2z.stakingsreward.art
 - akt.stakingsreward.art


ROOT: stakingsreward.pro
Subdomains: 93
Saved lines: 92
Examples:
 - 0g.stakingsreward.pro
 - 1inch.stakingsreward.pro
 - 2z.stakingsreward.pro
 - akt.stakingsreward.pro


ROOT: login-coinbase-secured.com
Subdomains: 88
Saved lines: 87
Examples:
 - 23205546-4573-41c2-b0cf-f0c8d70bd18a.login-coinbase-secured.com
 - 4b5295d3-97e6-405a-be3a-dccb907e0f1a.login-coinbase-secured.com
 - admin.login-coinbase-secured.com


ROOT: mystrikingly.com
Subdomains: 87
Saved lines: 86
Examples:
 - app--phantom--wallet--extension.mystrikingly.com
 - app-phantom-extension.mystrikingly.com
 - argentxwallet-extensionn.mystrikingly.com
 - argentxwalletextension.mystrikingly.com


ROOT: airdropsalert.click
Subdomains: 87
Saved lines: 86
Examples:
 - 1inch.airdropsalert.click
 - abstract.airdropsalert.click
 - aca.airdropsalert.click

ROOT: airdropalerts.one
Subdomains: 84
Saved lines: 83
Examples:
 - 0g.airdropalerts.one
 - 1inch.airdropalerts.one
 - 2z.airdropalerts.one


ROOT: airdropalert.us
Subdomains: 83
Saved lines: 82
Examples:
 - 1inch.airdropalert.us
 - abstract.airdropalert.us
 - aethir.airdropalert.us

ROOT: airdropsalert.sbs
Subdomains: 81
Saved lines: 80
Examples:
 - 1inch.airdropsalert.sbs
 - 7kdefi.airdropsalert.sbs
 - abstract.airdropsalert.sbs


ROOT: airdropsalert.us
Subdomains: 80
Saved lines: 79
Examples:
 - 1inch.airdropsalert.us
 - abstract.airdropsalert.us
 - aethir.airdropsalert.us
 - akt.airdropsalert.us


ROOT: coinbase-assists.com
Subdomains: 79
Saved lines: 78
Examples:
 - 1mhuflwnz.trendyolal31.coinbase-assists.com
 - 34776500-d824-4134-aa6f-2b2e307b4256.coinbase-assists.com
 - 7b38e3a7-80dc-4bcf-a3f0-a3722feb2671.coinbase-assists.com

ROOT: satlayers.xyz
Subdomains: 77
Saved lines: 76
Examples:
 - 014w8.satlayers.xyz
 - 16bz5.satlayers.xyz
 - 1846m.satlayers.xyz


ROOT: stakingsreward.org
Subdomains: 77
Saved lines: 76
Examples:
 - 0g.stakingsreward.org
 - 1inch.stakingsreward.org
 - 2z.stakingsreward.org


ROOT: magmaheartforger.top
Subdomains: 76
Saved lines: 75
Examples:
 - dakcc.magmaheartforger.top
 - fcctr.magmaheartforger.top
 - jobsar.magmaheartforger.top


ROOT: stakingsrewards.club
Subdomains: 74
Saved lines: 73
Examples:
 - 0g.stakingsrewards.club
 - 1inch.stakingsrewards.club
 - 2z.stakingsrewards.club

ROOT: stakingreward.dev
Subdomains: 74
Saved lines: 73
Examples:
 - 0g.stakingreward.dev
 - 1inch.stakingreward.dev
 - 2z.stakingreward.dev

ROOT: stakingrewards.biz
Subdomains: 72
Saved lines: 71
Examples:
 - 0g.stakingrewards.biz
 - 1inch.stakingrewards.biz
 - 2z.stakingrewards.biz


ROOT: beefyapps.lat
Subdomains: 71
Saved lines: 70
Examples:
 - 1inch.beefyapps.lat
 - abstract.beefyapps.lat
 - aethir.beefyapps.lat

ROOT: airdrpsalerts.info
Subdomains: 69
Saved lines: 68
Examples:
 - 1inch.airdrpsalerts.info
 - abstract.airdrpsalerts.info
 - aethir.airdrpsalerts.info


ROOT: airdropalerts.pro
Subdomains: 68
Saved lines: 67
Examples:
 - 0g.airdropalerts.pro
 - 1inch.airdropalerts.pro
 - 2z.airdropalerts.pro
 - akt.airdropalerts.pro

ROOT: airdropalerts.vip
Subdomains: 68
Saved lines: 67
Examples:
 - 0g.airdropalerts.vip
 - 1inch.airdropalerts.vip
 - 2z.airdropalerts.vip


ROOT: framer.app
Subdomains: 66
Saved lines: 65
Examples:
 - app-coinebase-helps.framer.app
 - aquamarine-suggestions-419283.framer.app
 - auth-new-coinbase.framer.app

ROOT: beefyapps.cfd
Subdomains: 66
Saved lines: 65
Examples:
 - 1inch.beefyapps.cfd
 - abstract.beefyapps.cfd
 - aethir.beefyapps.cfd


ROOT: airdrpsalert.club
Subdomains: 65
Saved lines: 64
Examples:
 - 1inch.airdrpsalert.club
 - abstract.airdrpsalert.club
 - aethir.airdrpsalert.club


ROOT: airdropsalert.app
Subdomains: 65
Saved lines: 64
Examples:
 - 1inch.airdropsalert.app
 - abstract.airdropsalert.app
 - aethir.airdropsalert.app


ROOT: beefyhubs.life
Subdomains: 64
Saved lines: 63
Examples:
 - 1inch.beefyhubs.life
 - abstract.beefyhubs.life
 - aethir.beefyhubs.life

ROOT: airdrpsalerts.lat
Subdomains: 62
Saved lines: 61
Examples:
 - 1inch.airdrpsalerts.lat
 - abstract.airdrpsalerts.lat
 - aethir.airdrpsalerts.lat


ROOT: stakingsreward.vip
Subdomains: 61
Saved lines: 60
Examples:
 - 0g.stakingsreward.vip
 - 1inch.stakingsreward.vip
 - akt.stakingsreward.vip


ROOT: beefyapps.sbs
Subdomains: 60
Saved lines: 59
Examples:
 - abstract.beefyapps.sbs
 - akt.beefyapps.sbs
 - arb.beefyapps.sbs


ROOT: airdrpsalert.life
Subdomains: 60
Saved lines: 59
Examples:
 - 1inch.airdrpsalert.life
 - abstract.airdrpsalert.life
 - aethir.airdrpsalert.life


ROOT: airdropsalert.bar
Subdomains: 60
Saved lines: 59
Examples:
 - 1inch.airdropsalert.bar
 - abstract.airdropsalert.bar
 - aethir.airdropsalert.bar


ROOT: airdrpsalert.lol
Subdomains: 60
Saved lines: 59
Examples:
 - 1inch.airdrpsalert.lol
 - abstract.airdrpsalert.lol
 - akt.airdrpsalert.lol

ROOT: portal-hubs.sbs
Subdomains: 60
Saved lines: 59
Examples:
 - 1inch.portal-hubs.sbs
 - abstract.portal-hubs.sbs
 - aethir.portal-hubs.sbs


ROOT: beefyapps.lol
Subdomains: 59
Saved lines: 58
Examples:
 - 1inch.beefyapps.lol
 - aethir.beefyapps.lol
 - akt.beefyapps.lol

Lazy sub optimal script which could generate a PR friendly patch

#!/usr/bin/env python3
"""


Goal:
- Detect redundant subdomain block clusters
- Works across ccTLDs + gTLDs WITHOUT TLD list dependency
- Uses structural + frequency heuristics
- Generates GitHub-ready patch file
"""

import json
import sys
import urllib.request
from collections import defaultdict
import difflib

URL = "https://raw.githubusercontent.com/MetaMask/eth-phishing-detect/main/src/config.json"

# Cleaned IGNORE list (deduplicated + safe platforms only)
IGNORE_ROOTS = {
    "github.io", "gitbook.io", "ghost.io", "mssg.me",
    "githubusercontent.com", "typedream.app", "godaddysites.com",
    "vercel.app", "pages.dev", "workers.dev",
    "r2.dev", "webflow.io", "netlify.app",
    "wixsite.com", "blogspot.com",
    "squarespace.com", "notion.site", "teachable.com", "framer.ai",
    "google.com", "googleusercontent.com",
    "tumblr.com", "wordpress.com", "wpcomstaging.com",
    "cloudflare.com", "cloudflarepages.com",
    "render.com", "fly.io",
    "herokuapp.com", "firebaseapp.com",
    "surge.sh", "now.sh",
    "zeit.co", "appspot.com", "app.goo.gl",
    "vittaweb.com", "godaddy.site", "godaddy.com",
    "shopify.com", "myshopify.com",
    "godx.ai", "wordpress.net",
    "webnode.com", "webnodecloud.com",
    "ucloude.com", "weebly.com",
    "weeblysite.com",
    "quarespace.net", "sandcastlesite.com",
    "wordpress.org", "wpengine.com",
    "bluehost.com", "hostgator.com",
    "namecheap.com", "domains.google",
    "domain.com", "web.app", "wixstudio.com",
    "sitebuilder.com", "webstarts.com", "wstd.io",
    "azurewebsites.net",
    "dweb.link", "framer.website", "onrender.com", "canva.site",
    "bravesites.com", "4everland.app", "duckdns.org",
    "eth.limo", "dora.run", "newzenler.com",
    "square.site", "000.pe", "ddns.net", "ddnss.eu"
}

COMMON_2LEVEL_CC = {
    "co.uk","org.uk","gov.uk","ac.uk",
    "com.au","net.au","org.au",
    "co.jp","com.br","com.mx","com.tr",
    "co.nz","com.sg","com.hk"
}


def load():
    if len(sys.argv) > 1:
        with open(sys.argv[1], "r", encoding="utf-8") as f:
            return json.load(f)
    return json.loads(urllib.request.urlopen(URL).read().decode())


def norm(d):
    return d.lower().strip(".")


def guess_roots(domain):
    parts = domain.split(".")

    if len(parts) <= 2:
        return [domain]

    last2 = ".".join(parts[-2:])
    last3 = ".".join(parts[-3:])

    if last2 in COMMON_2LEVEL_CC and len(parts) >= 3:
        return [".".join(parts[-3:])]

    return [last2, last3]


def build_patch(original_entries, candidates):
    original_lines = sorted(set(original_entries))
    modified = set(original_lines)

    for root, _, subs in candidates:
        subs_set = set(subs)
        modified -= subs_set
        modified.add(root)

    modified_lines = sorted(modified)

    diff = difflib.unified_diff(
        original_lines,
        modified_lines,
        fromfile="a/src/config.json",
        tofile="b/src/config.json",
        lineterm=""
    )

    return "\n".join(diff)


def main():
    data = load()

    entries = data.get("blacklist", [])
    raw = set(norm(x) for x in entries)

    root_map = defaultdict(set)

    for d in raw:
        roots = guess_roots(d)
        for r in roots:
            if r not in IGNORE_ROOTS:
                root_map[r].add(d)

    candidates = []

    for root, members in root_map.items():
        if len(members) < 2:
            continue

        subdomains = [m for m in members if m != root and m.endswith(root)]

        if len(subdomains) < 2:
            continue

        candidates.append((root, len(subdomains), subdomains))

    candidates.sort(key=lambda x: x[1], reverse=True)

    total_saved = 0

    print("=" * 80)
    print("MetaMask Redundant Root-Domain Candidates")
    print("=" * 80)

    for root, count, subs in candidates:
        saved = count - 1
        total_saved += saved

        print(f"\nROOT: {root}")
        print(f"Subdomains: {count}")
        print(f"Saved lines: {saved}")
        print("Examples:")
        for s in sorted(subs)[:10]:
            print(" -", s)

    print("\n" + "=" * 80)
    print("TOTAL ROOT CANDIDATES:", len(candidates))
    print("TOTAL LINES SAVABLE:", total_saved)
    print("=" * 80)

    # Generate patch file
    patch = build_patch(entries, candidates)

    with open("metamask_redundant_cleanup.patch", "w", encoding="utf-8") as f:
        f.write(patch)

    print("\nPATCH FILE GENERATED:")
    print(" -> metamask_redundant_cleanup.patch")


if __name__ == "__main__":
    main()

Thanks

Metadata

Metadata

Assignees

No one assigned

    Labels

    improvementIssue or PR for features in the software of this repo

    Type

    No type
    No fields configured for issues without a type.

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions