registry/internal/api/handlers/v0/auth
Repository files (latest commit first)
Filename Latest commit message Latest commit date
Sash 5c19656cb9
fix(auth): reject github.io domains in DNS/HTTP token exchange (org namespace takeover) (#1506)
## 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](https://cursor.com)

Signed-off-by: SashaMIT <sash@ela.city>
Co-authored-by: Cursor <cursoragent@cursor.com>
2026-08-07 01:38:34 +03:00
..
common.go fix(auth): reject github.io domains in DNS/HTTP token exchange (org namespace takeover) (#1506) 2026-08-07 01:38:34 +03:00
common_test.go fix(auth): reject github.io domains in DNS/HTTP token exchange (org namespace takeover) (#1506) 2026-08-07 01:38:34 +03:00
dns.go fix(auth): better DNS verification errors and wrong-selector hint (#1202) 2026-04-25 11:22:06 -04:00
dns_test.go security: fix open redirect and add small hardening (#1227) 2026-04-29 19:14:00 -04:00
github_at.go docs(auth): document fine-grained PAT permission for org publishing (+ pagination-cap test) (#1435) 2026-07-10 18:48:56 -04:00
github_at_internal_test.go fix(auth): grant org namespace only to org Owners, not all members (#1383) 2026-07-10 17:05:47 -04:00
github_at_test.go docs(auth): document fine-grained PAT permission for org publishing (+ pagination-cap test) (#1435) 2026-07-10 18:48:56 -04:00
github_oidc.go refactor: rename readBody to readErrorBody and cap body size (#1246) 2026-05-04 07:09:57 -04:00
github_oidc_test.go auth: bind GitHub OIDC token exchange to a per-deployment audience (#1229) 2026-04-29 20:27:26 -04:00
http.go fix(auth/http): extend SSRF blocklist to IPv6 6to4/NAT64/site-local prefixes (#1250) 2026-05-04 09:41:23 -04:00
http_internal_test.go fix(auth/http): extend SSRF blocklist to IPv6 6to4/NAT64/site-local prefixes (#1250) 2026-05-04 09:41:23 -04:00
http_test.go security: fix open redirect and add small hardening (#1227) 2026-04-29 19:14:00 -04:00
main.go Introduce v0.1 version of the API (#658) 2025-10-14 11:04:48 +03:00
none.go Replace / with - for operation IDs (#660) 2025-10-14 15:26:43 +03:00
none_test.go Changes on the server.json format and the API (#562) 2025-09-29 23:30:35 +03:00
oidc.go auth/oidc: support slice-typed extra claims via overlap match (#1238) 2026-05-04 06:24:34 -04:00
oidc_internal_test.go auth/oidc: test slice-typed extra claims comparison (#1245) 2026-05-04 06:52:12 -04:00
oidc_test.go Stop pinning Go to patch versions, use stable in CI (#1137) 2026-04-09 11:57:21 -04:00