Skip to content

chore(moshpit): revoke the 622 endings that collide with real TLDs - #476

Merged
ralyodio merged 1 commit into
mainfrom
chore/revoke-real-tlds
Aug 30, 2026
Merged

chore(moshpit): revoke the 622 endings that collide with real TLDs#476
ralyodio merged 1 commit into
mainfrom
chore/revoke-real-tlds

Conversation

@ralyodio

Copy link
Copy Markdown
Contributor

.sh was sold through the ordinary registration flow, for $2, to someone unrelated to this project. It's Saint Helena's ccTLD — and it's where this registry lives: pit.moshcode.sh. Every bridge that loaded the ending list then classified the registry as a Moshpit name, refused to forward it, and tried to resolve it through the registry it had just made unreachable. Machines running a bridge answered NXDOMAIN to the entire internet, and took the real .sh ccTLD with them.

v0.80.0 closed both halves going forward. This removes the ones already sold: 622 endings across 14 owners.

Archived, not dropped

Selling an ending took money, and the directory row is the only record of who holds what. Rows move to moshpit_tlds_removed with owner, price and original claim time intact — readable, refundable against, restorable.

moshpit_tld_log is the append-only record this schema already keeps, and gains a revoke entry per ending, so the history reads as a claim that was revoked rather than one that silently stopped existing.

Nothing cascades. moshpit_offers, moshpit_name_purchases and the rest store the ending as plain text with no foreign key, so offers and purchases against a revoked ending survive and stay auditable.

Tested, not reviewed

This runs once, against production, deleting rows people paid for. So it's executed in apps/pwa/test/moshpit-revoke-real-tlds.test.mjs against the real schema and the real 1438-entry list, splitting statements exactly as migrate.mjs does.

The failure worth guarding against isn't that it errors — it's that it removes one row too many, which on this table means taking someone's ending away, and which nothing downstream would notice.

assertion
.hacker, .2600, .eggs, .moshpit, .42 still present
.sh, .ai, .dev, .com, xn--p1ai removed
archive keeps owner, price, created_at
a revocation logged for each
an offer against a revoked ending survives
running it twice removes nothing further

Suite: 2754 tests, 0 failures.

Deployment

Merging is the deploy — Railway redeploys and main() awaits migrate() before listen(), so this runs on the next boot. Irreversible in the directory (recoverable from moshpit_tlds_removed).

Owner breakdown at time of writing: 334 of the 622 belong to 0999fea1f2eefd79, 166 to 240492d23bed3d38, 86 to ee90bbf32f9ecf01 (who holds .sh), and the rest spread across 11 owners.

🤖 Generated with Claude Code

https://claude.ai/code/session_01ThnQwoieWt8VR6N7gtgnhp

`.sh` was sold through the ordinary registration flow, for $2, to someone
unrelated to this project. It is Saint Helena's ccTLD and it is also where this
registry lives: pit.moshcode.sh. Every bridge that loaded the ending list then
classified the registry as a Moshpit name, refused to forward it, and tried to
resolve it through the registry it had just made unreachable — so machines
running a bridge answered NXDOMAIN to the entire internet, and took the rest of
the real .sh ccTLD down with them.

v0.80.0 closed both halves going forward: the registry stopped selling endings
IANA delegates, and bridges stopped answering for the ones already sold. This
removes those from the directory. 622 endings, across 14 owners, at the time of
writing.

Archived rather than dropped. Selling an ending took money and the directory row
is the only record of who holds what, so the rows move to `moshpit_tlds_removed`
with their owner, price and original claim time intact — readable, refundable
against, restorable. `moshpit_tld_log` is the append-only record this schema
already keeps, and gains a `revoke` entry per ending, so the history reads as a
claim that was revoked rather than one that silently stopped existing.

Nothing cascades. moshpit_offers, moshpit_name_purchases and the rest store the
ending as plain text with no foreign key, so an offer or a purchase against a
revoked ending survives and stays auditable.

Tested rather than reviewed. The migration is executed in
apps/pwa/test/moshpit-revoke-real-tlds.test.mjs against the real schema and the
real 1438-entry list, splitting statements exactly as migrate.mjs does. The
failure worth guarding against is not that it errors — it is that it removes one
row too many, which on this table means taking someone's ending away and which
nothing downstream would notice. So `.hacker`, `.2600`, `.eggs`, `.moshpit` and
`.42` are asserted present afterwards, punycode (`xn--p1ai`) is asserted removed,
the archive is asserted to carry owner and price, and running it twice is
asserted to remove nothing further.

Suite: 2754 tests, 0 failures.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01ThnQwoieWt8VR6N7gtgnhp
@github-actions

Copy link
Copy Markdown

ThreatCrush Security Scan

0 finding(s) in the 2 file(s) this pull request changes.

Nothing in the files this pull request changes.

91 pre-existing finding(s) elsewhere in the repository — **HIGH/CRITICAL**: 8 | **MEDIUM**: 73 | **LOW**: 10

Not introduced by this pull request. The full set is in the Security tab.

Severity Rule Location
HIGH js-ssrf-outbound-request apps/pwa/public/sw.js:45
HIGH tls-verification-disabled apps/pwa/src/lib/moshpit-gateway.mjs:299
HIGH sh-remote-script-execution install.sh:86
HIGH sh-remote-script-execution install.sh:90
HIGH sh-remote-script-execution install.sh:202
HIGH sh-remote-script-execution install.sh:213
HIGH sh-remote-script-execution install.sh:219
HIGH tls-verification-disabled src/dns.mjs:766
MEDIUM sql-template-interpolation apps/pwa/src/moshpit.mjs:139
MEDIUM sql-template-interpolation apps/pwa/src/moshpit.mjs:153
MEDIUM sql-template-interpolation apps/pwa/src/moshpit.mjs:179
MEDIUM sql-template-interpolation apps/pwa/src/moshpit.mjs:373
MEDIUM sql-template-interpolation apps/pwa/src/moshpit.mjs:377
MEDIUM sql-template-interpolation apps/pwa/src/moshpit.mjs:422
MEDIUM sql-template-interpolation apps/pwa/src/moshpit.mjs:671
MEDIUM sql-template-interpolation apps/pwa/src/moshpit.mjs:867
MEDIUM sql-template-interpolation apps/pwa/src/moshpit.mjs:869
MEDIUM sql-template-interpolation apps/pwa/src/moshpit.mjs:928
MEDIUM sql-template-interpolation apps/pwa/src/moshpit.mjs:974
MEDIUM sql-template-interpolation apps/pwa/src/moshpit.mjs:1044

…and 71 more. Full results in the Security tab.

Snippets are redacted; ThreatCrush never prints matched credential material.

@ralyodio
ralyodio merged commit a2a630d into main Aug 30, 2026
6 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant