Skip to content

fix(auth): reject github.io domains in DNS/HTTP token exchange (org namespace takeover) - #1506

Open
SashaMIT wants to merge 1 commit into
modelcontextprotocol:mainfrom
SashaMIT:fix/block-github-pages-domain-auth
Open

fix(auth): reject github.io domains in DNS/HTTP token exchange (org namespace takeover)#1506
SashaMIT wants to merge 1 commit into
modelcontextprotocol:mainfrom
SashaMIT:fix/block-github-pages-domain-auth

Conversation

@SashaMIT

@SashaMIT SashaMIT commented Aug 5, 2026

Copy link
Copy Markdown

Summary

  • The GitHub token method grants io.github.<org>/* publish rights only to org Owners (active admin membership — github_at.go).
  • The DNS/HTTP token methods grant reversed(domain)/* for any proven domain, with no github.io special-casing and an empty BlockedNamespaces list.
  • <org>.github.io is served by GitHub Pages from the <org>/<org>.github.io repository. Push access to that one repository — routinely held by ordinary org members, a much weaker bar than Owner — is enough to serve a key at /.well-known/mcp-registry-auth, exchange it for a JWT, and publish under the org's entire io.github.<org>/* namespace.
  • Reject github.io (and subdomains) at the shared ValidateDomainAndTimestamp seam used by both DNS and HTTP exchange; io.github.* publishers already have the GitHub method.

Impact if unsolved

Any org member with write access to the org's GitHub Pages repo (or an attacker compromising such a member) can mint MCP packages under the org's trusted namespace — supply-chain poisoning of every downstream user who installs <org>'s servers from the registry, bypassing the deliberate Owner-only gate.

Test plan

  • New TestValidateDomainAndTimestampRejectsGitHubPages: rejects my-org.github.io (incl. mixed case and subdomains), still allows lookalikes (github.io.evil-example.com, my-org.github.io.example.com) and ordinary domains.
  • Full internal/api/handlers/v0/auth package passes.

Made with Cursor

The GitHub method grants io.github.<org>/* only to org Owners (active admin membership). The DNS/HTTP exchange granted reversed(domain)/* for any proven domain with no github.io special-casing and an empty BlockedNamespaces list. Since <org>.github.io is served from the <org>/<org>.github.io Pages repository, anyone with push access to that single repo — ordinary org members, far below Owner — could serve a key at /.well-known/mcp-registry-auth and mint publish rights over the whole org namespace, defeating the documented Owner-only gate. Reject github.io and its subdomains at the shared ValidateDomainAndTimestamp seam; io.github.* publishers use the GitHub method.

Signed-off-by: SashaMIT <sash@ela.city>
Co-authored-by: Cursor <cursoragent@cursor.com>
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