Skip to content

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

Merged
rdimitrov merged 1 commit into
modelcontextprotocol:mainfrom
SashaMIT:fix/block-github-pages-domain-auth
Aug 6, 2026
Merged

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

Conversation

@SashaMIT

@SashaMIT SashaMIT commented Aug 5, 2026

Copy link
Copy Markdown
Contributor

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>

@rdimitrov rdimitrov left a comment

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Reviewed the authentication boundary, suffix matching, handler coverage, and compatibility impact. The issue is valid; this safely closes the GitHub Pages path to io.github organization namespace grants. Targeted auth tests, race tests, and merge-with-current-main checks pass. Approved.

@rdimitrov
rdimitrov requested a balanced review from Copilot August 6, 2026 22:38
@rdimitrov
rdimitrov merged commit 5c19656 into modelcontextprotocol:main Aug 6, 2026
3 checks passed

Copilot AI left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

Blocks GitHub Pages domains from DNS/HTTP authentication to prevent organization namespace takeover.

Changes:

  • Rejects github.io and its subdomains case-insensitively.
  • Adds coverage for blocked domains, lookalikes, and ordinary domains.

Reviewed changes

Copilot reviewed 2 out of 2 changed files in this pull request and generated no comments.

File Description
internal/api/handlers/v0/auth/common.go Adds shared GitHub Pages domain rejection.
internal/api/handlers/v0/auth/common_test.go Tests rejection and allowed-domain behavior.

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.

3 participants