Skip to content

fix(registries): block IPv6 transition addresses in the SSRF guard - #1235

Open
aroh3006 wants to merge 1 commit into
smart-mcp-proxy:mainfrom
aroh3006:ssrf-ipv6-transition
Open

fix(registries): block IPv6 transition addresses in the SSRF guard#1235
aroh3006 wants to merge 1 commit into
smart-mcp-proxy:mainfrom
aroh3006:ssrf-ipv6-transition

Conversation

@aroh3006

Copy link
Copy Markdown

Description

isBlockedIP is the single predicate behind the pre-flight URL check, the dial-time Control guard and the app-layer target-host guard. It checks IsLoopback/IsPrivate/link-local/etc on the resolved address but never looks at the IPv4 address embedded in an IPv6 transition address, so a registry source URL whose host is [2002:a9fe:a9fe::1] (6to4) or [64:ff9b::a9fe:a9fe] (NAT64 well-known prefix) passes all three layers. On a host with NAT64/6to4 routing that address reaches the embedded IPv4, so registry add-source pointed at one of these forms can still get the daemon to fetch from 169.254.169.254 or a loopback service.

This unwraps 6to4, NAT64 (well-known and local-use prefixes), Teredo and the deprecated IPv4-compatible form and re-checks the embedded address. A NAT64 address wrapping a public IPv4 stays reachable. Same class as CVE-2026-73087 (Dozzle).

Testing

  • I have tested these changes locally
  • I have added/updated tests that prove my fix is effective or my feature works
  • All existing tests pass

go test ./internal/registries/ passes. The new transition-address entries in TestIsBlockedIP are accepted by the current guard and rejected after the change; the existing entries still pass. gofmt and go vet clean.

isBlockedIP checked IsLoopback/IsPrivate/etc on the address but never
looked at the IPv4 embedded in an IPv6 transition address, so a registry
source URL with a host like [2002:a9fe:a9fe::1] (6to4) or
[64:ff9b::a9fe:a9fe] (NAT64) passed the pre-flight check, the dial-time
Control guard and the app-layer guard, and on a host with NAT64/6to4
routing could reach 169.254.169.254 or a loopback service.

Unwrap 6to4, NAT64, Teredo and the deprecated IPv4-compatible form and
re-check the embedded address. A NAT64 address wrapping a public IPv4
stays reachable.
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