decision: the phishing blocklist URL embeds a competitor's org name, and its documented upstream no longer exists #219

Closed
opened 2026-08-11 14:41:30 +02:00 by clawbot · 2 comments
Collaborator

BLOCKLIST_URL at src/shared/phishingDomains.js:17 embeds a competitor's org name in the URL string. RULES.md:121 bars competitor names in code and documentation, and says the code must change to match the rule. The same name appears in a comment at tests/e2e/network.js:274.

There is no drop-in replacement: AugurProject/eth-phishing-detect, which README.md and LICENSE:685 both cite as the source, returns 404 — that repo is gone. The competitor's org fork is the only live upstream, so the vendored phishingBlocklist.json can only have come from there. Established while correcting the README in #213, which removed the dead link but deliberately left the code and the LICENSE line alone.

This is not the same question as the isMetaMask shim in #165: that one is a protocol identifier dApps feature-detect, whereas this is a hostname we choose to fetch from, and we could choose otherwise.

Options

  • (a) Mirror the list under your own host and fetch from there. Removes the name, removes a third-party runtime dependency for a security-relevant feed, and puts the update cadence under your control. Costs hosting and a refresh mechanism, and makes you responsible for staleness — a stale phishing list is a silent safety regression.
  • (b) Keep fetching upstream and document an explicit exception, as the Crypto Policy already does for sanctioned exceptions. Zero engineering cost; leaves the name in shipped code.
  • (c) Assemble the URL from parts so the literal name does not appear. Satisfies a grep and nothing else — the request still goes to the same host and any reader sees it immediately.

Recommendation

(a). A wallet's anti-phishing feed is security-relevant infrastructure, and fetching it from a competitor's repository means they can change what your users are warned about. The naming rule is the smaller reason to move it. If the hosting cost is unwanted, (b) is honest and defensible; (c) is not — it hides the fact rather than changing it.

Whichever you pick, LICENSE:685 needs its dead AugurProject URL corrected in the same unit.

Definition of done (once decided)

  • grep -ri for the competitor name across the repo returns only the deliberate isMetaMask shim in src/content/inpage.js, or documented exceptions.
  • LICENSE:685 no longer cites a URL that 404s.
  • The blocklist still loads and the phishing warnings still fire, proven in the e2e harness.
  • TODO.md updated in the same commit.
  • make check passes.
`BLOCKLIST_URL` at `src/shared/phishingDomains.js:17` embeds a competitor's org name in the URL string. `RULES.md:121` bars competitor names in code and documentation, and says the code must change to match the rule. The same name appears in a comment at `tests/e2e/network.js:274`. There is no drop-in replacement: `AugurProject/eth-phishing-detect`, which `README.md` and `LICENSE:685` both cite as the source, returns **404** — that repo is gone. The competitor's org fork is the only live upstream, so the vendored `phishingBlocklist.json` can only have come from there. Established while correcting the README in https://git.eeqj.de/sneak/AutistMask/issues/213, which removed the dead link but deliberately left the code and the `LICENSE` line alone. This is not the same question as the `isMetaMask` shim in https://git.eeqj.de/sneak/AutistMask/issues/165: that one is a protocol identifier dApps feature-detect, whereas this is a hostname we choose to fetch from, and we could choose otherwise. ## Options - **(a) Mirror the list under your own host** and fetch from there. Removes the name, removes a third-party runtime dependency for a security-relevant feed, and puts the update cadence under your control. Costs hosting and a refresh mechanism, and makes you responsible for staleness — a stale phishing list is a silent safety regression. - **(b) Keep fetching upstream and document an explicit exception**, as the Crypto Policy already does for sanctioned exceptions. Zero engineering cost; leaves the name in shipped code. - **(c) Assemble the URL from parts** so the literal name does not appear. Satisfies a grep and nothing else — the request still goes to the same host and any reader sees it immediately. ## Recommendation **(a).** A wallet's anti-phishing feed is security-relevant infrastructure, and fetching it from a competitor's repository means they can change what your users are warned about. The naming rule is the smaller reason to move it. If the hosting cost is unwanted, **(b)** is honest and defensible; **(c)** is not — it hides the fact rather than changing it. Whichever you pick, `LICENSE:685` needs its dead `AugurProject` URL corrected in the same unit. ## Definition of done (once decided) - [ ] `grep -ri` for the competitor name across the repo returns only the deliberate `isMetaMask` shim in `src/content/inpage.js`, or documented exceptions. - [ ] `LICENSE:685` no longer cites a URL that 404s. - [ ] The blocklist still loads and the phishing warnings still fire, proven in the e2e harness. - [ ] `TODO.md` updated in the same commit. - [ ] `make check` passes.
clawbot added this to the 1.0.0 milestone 2026-08-11 14:41:30 +02:00
sneak was assigned by clawbot 2026-08-11 14:41:30 +02:00
Owner

i think we should automate vendoring it (and censoring it) as part of the build process.

i think we should automate vendoring it (and censoring it) as part of the build process.
sneak removed their assignment 2026-08-17 08:11:24 +02:00
clawbot was assigned by sneak 2026-08-17 08:11:24 +02:00
Author
Collaborator

Decision recorded: automate the vendoring and the censoring in the build. Implementation requirements below; this supersedes options (a), (b) and (c) in the issue body.

The naming violation lives in SHIPPED code — BLOCKLIST_URL at src/shared/phishingDomains.js:17 is fetched by the extension at runtime. A build-time vendoring script is repo tooling, not shipped to users, so the name can remain there where it is a factual source reference and cannot be avoided. That distinction is what makes this work.

Requirements

  • Add a script/ entrypoint that fetches the upstream list, censors it, and writes src/shared/phishingBlocklist.json. POSIX sh, per scripts-to-rule-them-all.
  • Pin by cryptographic hash. REPO_POLICIES.md:22 requires it for all external references, and the current URL tracks main, a moving ref that cannot be pinned. Fetch a pinned commit, and assert the fetched content's hash matches a recorded expectation — a vendoring step that silently accepts whatever it is served is a supply-chain hole in a security feed.
  • Censor the shipped artifact: no competitor name in src/shared/phishingBlocklist.json, in src/shared/phishingDomains.js, or anywhere else that reaches dist/. Note the upstream JSON carries metadata fields beyond blacklist; check what is actually in there rather than assuming only the URL matters.
  • Remove the runtime fetch. It is the source of the violation, and it also means a third party controls what our users are warned about. Deleting it removes both. This retires the delta/persistence machinery from #158 and the alarm that drives it — remove them properly, do not leave dead code.
  • LICENSE:685 cites a URL that 404s; correct it in the same unit.
  • The vendored list is 8.7 MB. State in the PR body what the change does to dist/ size, and whether the censoring step alters it.

Disclosure required in the PR body, not buried

Removing the runtime refresh means the blocklist is only as fresh as the last build. Today it self-updates every 24 hours. Say plainly what the staleness window becomes and how a refresh reaches users. If that trade is wrong, this is the unit to say so on rather than after it lands.

Definition of done

  • grep -ri for the competitor name across the repo returns only the build-time vendoring script and the deliberate isMetaMask shim in src/content/inpage.js.
  • Nothing under dist/ contains the name, asserted by a check that runs in make check.
  • The vendoring script is reproducible: run twice, identical output, and it fails loudly on a hash mismatch.
  • The blocklist still loads and the phishing warnings still fire, proven in the e2e harness.
  • LICENSE:685 no longer cites a URL that 404s.
  • TODO.md updated in the same commit.
  • make check passes.
Decision recorded: automate the vendoring and the censoring in the build. Implementation requirements below; this supersedes options (a), (b) and (c) in the issue body. The naming violation lives in SHIPPED code — `BLOCKLIST_URL` at `src/shared/phishingDomains.js:17` is fetched by the extension at runtime. A build-time vendoring script is repo tooling, not shipped to users, so the name can remain there where it is a factual source reference and cannot be avoided. That distinction is what makes this work. ## Requirements - Add a `script/` entrypoint that fetches the upstream list, censors it, and writes `src/shared/phishingBlocklist.json`. POSIX sh, per scripts-to-rule-them-all. - **Pin by cryptographic hash.** `REPO_POLICIES.md:22` requires it for all external references, and the current URL tracks `main`, a moving ref that cannot be pinned. Fetch a pinned commit, and assert the fetched content's hash matches a recorded expectation — a vendoring step that silently accepts whatever it is served is a supply-chain hole in a security feed. - **Censor the shipped artifact**: no competitor name in `src/shared/phishingBlocklist.json`, in `src/shared/phishingDomains.js`, or anywhere else that reaches `dist/`. Note the upstream JSON carries metadata fields beyond `blacklist`; check what is actually in there rather than assuming only the URL matters. - **Remove the runtime fetch.** It is the source of the violation, and it also means a third party controls what our users are warned about. Deleting it removes both. This retires the delta/persistence machinery from https://git.eeqj.de/sneak/AutistMask/issues/158 and the alarm that drives it — remove them properly, do not leave dead code. - `LICENSE:685` cites a URL that 404s; correct it in the same unit. - The vendored list is 8.7 MB. State in the PR body what the change does to `dist/` size, and whether the censoring step alters it. ## Disclosure required in the PR body, not buried Removing the runtime refresh means the blocklist is only as fresh as the last build. Today it self-updates every 24 hours. Say plainly what the staleness window becomes and how a refresh reaches users. If that trade is wrong, this is the unit to say so on rather than after it lands. ## Definition of done - [ ] `grep -ri` for the competitor name across the repo returns only the build-time vendoring script and the deliberate `isMetaMask` shim in `src/content/inpage.js`. - [ ] Nothing under `dist/` contains the name, asserted by a check that runs in `make check`. - [ ] The vendoring script is reproducible: run twice, identical output, and it fails loudly on a hash mismatch. - [ ] The blocklist still loads and the phishing warnings still fire, proven in the e2e harness. - [ ] `LICENSE:685` no longer cites a URL that 404s. - [ ] `TODO.md` updated in the same commit. - [ ] `make check` passes.
clawbot removed their assignment 2026-08-17 08:31:24 +02:00
sneak was assigned by clawbot 2026-08-17 08:31:24 +02:00
sneak was unassigned by clawbot 2026-08-17 08:33:22 +02:00
clawbot self-assigned this 2026-08-17 08:33:22 +02:00
Sign in to join this conversation.
2 Participants
Notifications
Due Date
No due date set.
Dependencies

No dependencies set.

Reference: sneak/AutistMask#219