registry/internal/api/handlers/v0/auth
Repository files (latest commit first)
Filename Latest commit message Latest commit date
Radoslav Dimitrov f5f40bd980
fix(auth/http): extend SSRF blocklist to IPv6 6to4/NAT64/site-local prefixes (#1250)
The HTTP namespace-verification fetcher's `isBlockedIP` composed its
blocklist from Go stdlib's `Is*` helpers plus a manual CGNAT range. That
covers IPv4 cloud metadata, RFC1918, ULA, and link-local — but Go's
classification helpers don't recognise IPv6 prefix families that embed
or tunnel to arbitrary IPv4:

  - 2002::/16       RFC 3056 6to4 — bits 16-47 are an arbitrary IPv4
  - 64:ff9b::/96    RFC 6052 NAT64 well-known — low 32 bits are IPv4
  - 64:ff9b:1::/48  RFC 8215 NAT64 local-use — same IPv4-embedding shape
  - fec0::/10       RFC 3879 site-local (deprecated, still routed by
                    some stacks)

On hosts with 6to4 routing or a NAT64 next-hop (the default on
IPv6-only GKE node pools, AWS IPv6-only EC2, Azure IPv6 VMs with
NAT64, and many corporate DNS64/NAT64 networks), an attacker who
controls DNS for a publisher domain can cause the registry to dial
`169.254.169.254`, `10.0.0.0/8`, etc. via the IPv6 wrapper. Same
SSRF class as GHSA-56c3-vfp2-5qqj on n8n-mcp.

Define the four prefixes via a new `mustCIDR` helper (panic on
malformed CIDR at init so a typo can't fail-open silently) and iterate
them in `isBlockedIP` after the stdlib gates. Refactor the existing
CGNAT IIFE to use the same helper for consistency. IPv4-mapped IPv6
(::ffff:0:0/96) needs no special-casing: Go's `Is*` helpers honour the
`To4()` fast-path, so e.g. `::ffff:10.0.0.1` is already classified as
`IsPrivate`.

Adds 17 test cases to `TestIsBlockedIP` covering each new prefix
family, IPv4-mapped IPv6 sanity checks, and just-outside-the-range
positive controls (`2001::1`, `2003::1`, `64:ff9c::1`).

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

Co-authored-by: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-05-04 09:41:23 -04:00
..
common.go refactor: rename readBody to readErrorBody and cap body size (#1246) 2026-05-04 07:09:57 -04:00
common_test.go security: fix open redirect and add small hardening (#1227) 2026-04-29 19:14:00 -04: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 refactor: rename readBody to readErrorBody and cap body size (#1246) 2026-05-04 07:09:57 -04:00
github_at_test.go Deduplicate server JSON structs between publisher and registry (#318) 2025-08-28 14:58:15 +01: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