Skip to content

feat(parking): host-parked Moshpit names go to the Pit too - #88

Merged
ralyodio merged 1 commit into
masterfrom
feat/host-parking-to-pit
Aug 1, 2026
Merged

feat(parking): host-parked Moshpit names go to the Pit too#88
ralyodio merged 1 commit into
masterfrom
feat/host-parking-to-pit

Conversation

@ralyodio

@ralyodio ralyodio commented Aug 1, 2026

Copy link
Copy Markdown
Collaborator

#87 moved /parking?name= to the Pit — but that isn't how a parked name actually arrives. The DNS resolver points an unpointed name at this app (DEFAULT_PARKING_HOST = moshcoding.com), so curl scrambled.eggs lands here as a Host header and still rendered the "IS COMING" tenant card.

Change

A name resolved from the Host now redirects to <pit>/n/<name>. An ordinary parked clearnet domain renders exactly as before.

Measured locally against the live registry:

Host result
scrambled.eggs 307https://pit.moshcode.sh/n/scrambled.eggs
hawaiian.chicken 307https://pit.moshcode.sh/n/hawaiian.chicken
moshcode.sh 200<title>Moshcode IS COMING</title> (tenant page, untouched)
app host 200 — the landing page

Three decisions worth flagging

Asked per name, not by pulling the ending list. /api/moshpit/tlds is capped at 200 and .eggs already falls outside it — matching against that list would quietly answer "no" for real names. resolve's registered flag has no such ceiling and means exactly "an ending the pit holds".

307, not 308. The owner can point the name at a real target at any moment; a permanent redirect cached in a browser would keep sending visitors here long after this app stopped being the answer. /parking keeps its 308, because that URL will always mean "go to the pit".

Fails closed. An unreachable Pit answers "not ours", so a registry outage leaves every parked domain rendering as it does today rather than bouncing the whole internet at /n/. Answers are memoised per name behind a 5-minute TTL, in a bounded map — Host is attacker-controlled, so the memo can't be allowed to grow without end.

Verification

  • bun test tests/157 pass, 0 fail (9 new), covering ours/not-ours, shape rejection without a request, memoisation, case normalisation, fail-closed on outage and non-200, and warm-cache survival
  • bun run build clean
  • Served locally and checked real status codes and Location headers with real Host headers — the table above is measured

🤖 Generated with Claude Code

#87 moved /parking?name= to the Pit, but that is not how a parked name
actually arrives. The DNS resolver points an unpointed name at this app
(DEFAULT_PARKING_HOST), so `curl scrambled.eggs` lands here as a Host
header and still rendered the "IS COMING" tenant card.

A name resolved from the Host now redirects to <pit>/n/<name>, while an
ordinary parked clearnet domain renders exactly as before.

Which is which is asked of the Pit per name, not by pulling its ending
list: that list is capped at 200 and `.eggs` already falls outside it, so
matching against it would quietly answer "no" for real names. resolve's
`registered` flag has no such ceiling.

307, not 308. The owner can point the name at a real target at any moment;
a permanent redirect cached in a browser would keep sending them here long
after this app stopped being the answer. /parking keeps its 308 — that URL
will always mean "go to the pit".

Fails closed: an unreachable Pit answers "not ours", so a registry outage
leaves every parked domain rendering as it does today rather than bouncing
the whole internet at /n/. Answers are memoised per name behind a 5-minute
TTL, with a bounded map because Host is attacker-controlled.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
@github-actions

github-actions Bot commented Aug 1, 2026

Copy link
Copy Markdown

vu1nz Security Review

0 finding(s) in PR #?

No security issues found.

@ralyodio
ralyodio merged commit 195a5d2 into master Aug 1, 2026
2 checks passed
@ralyodio
ralyodio deleted the feat/host-parking-to-pit branch August 1, 2026 04:44
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