Skip to content

fix: block IPv6 6to4, NAT64, site-local and CGNAT ranges in IsPublicIP#3031

Merged
dgageot merged 2 commits into
mainfrom
fix/ssrf-ipv6-cgnat
Jun 9, 2026
Merged

fix: block IPv6 6to4, NAT64, site-local and CGNAT ranges in IsPublicIP#3031
dgageot merged 2 commits into
mainfrom
fix/ssrf-ipv6-cgnat

Conversation

@ronan-thibaut-glitch

Copy link
Copy Markdown
Contributor

What

Extends IsPublicIP in pkg/httpclient/ssrf.go to block two categories of addresses that bypass the existing Go stdlib checks:

  • CGNAT 100.64.0.0/10 (RFC 6598): not covered by IsPrivate()
  • IPv6 prefix families that embed arbitrary IPv4 addresses:
    • 2002::/16 (RFC 3056, 6to4)
    • 64:ff9b::/96 (RFC 6052, NAT64 well-known)
    • 64:ff9b:1::/48 (RFC 8215, NAT64 local-use)
    • fec0::/10 (RFC 3879, site-local, deprecated)

On dual-stack or NAT64-enabled hosts (default in IPv6-only GKE, AWS IPv6-only EC2, Azure IPv6 VMs), addresses like 64:ff9b::a9fe:a9fe translate directly to 169.254.169.254 (cloud metadata). The existing blocklist did not catch these.

Also adds a mustCIDR helper that panics at startup on a malformed CIDR literal, replacing silent failure at runtime.

Why

Same class of vulnerability as GHSA-r48c-v28r-pf6v (modelcontextprotocol/registry), fixed upstream in their PR #1250. The IsPublicIP function is the SSRF guard for all outbound HTTP in docker-agent (fetch tool, api tool, openapi tool, a2a tool, MCP OAuth, skills cache, config loading). All verified live to pass the old filter.

Testing

29 new test cases in TestIsPublicIP and 5 new cases in TestSSRFDialControl, including concrete attack IPs (e.g. 2002:a9fe:a9fe:: which encodes 169.254.169.254) and boundary cases confirming no over-blocking.

@ronan-thibaut-glitch ronan-thibaut-glitch requested a review from a team as a code owner June 9, 2026 12:06
docker-agent

This comment was marked as low quality.

@aheritier aheritier added area/security Authentication, authorization, secrets, vulnerabilities kind/security Security fix or hardening PR labels Jun 9, 2026
@dgageot dgageot merged commit d433699 into main Jun 9, 2026
11 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

area/security Authentication, authorization, secrets, vulnerabilities kind/security Security fix or hardening PR

Projects

None yet

Development

Successfully merging this pull request may close these issues.

4 participants