GHSA-pph6-vfjv-vpjw: ToolHive: SSRF guard misses IPv6 NAT64 ranges (64:ff9b::/96, 64:ff9b:1::/48), allowing metadata/internal access behind a NAT64 gateway
Summary
ToolHive's hand-rolled private/reserved-IP SSRF guard (networking.IsPrivateIP in pkg/networking/utilities.go) does not recognize the IPv6 NAT64 address ranges — the well-known prefix 64:ff9b::/96 (RFC 6052) and the RFC 8215 local-use prefix 64:ff9b:1::/48. As a result, an address such as 64:ff9b:1::a9fe:a9fe — the NAT64 encoding of the link-local cloud metadata address 169.254.169.254 — is classified as a public, global-unicast address and the connection is allowed. On any ToolHive deployment that sits behind a NAT64/DNS64 gateway (the default networking stack in IPv6-only Kubernetes clusters and several IPv6-only cloud environments), an attacker who controls a URL that reaches this guard can have ToolHive attempt connections to internal/link-local addresses that the guard is meant to block, bypassing the SSRF protection. In practice the effect is a blind internal-reachability probe rather than metadata-credential theft (the only fully attacker-controlled path is HTTPS-only with TLS verification and does not reflect responses) — see Impact.
The most direct attacker-controlled entry point is the embedded OAuth authorization server's Client ID Metadata Document (CIMD) fetcher: an external OAuth client presents client_id=https://<attacker-domain>/path, and CIMDStorageDecorator.GetClient fetches that URL through the same guard. The same IsPrivateIP table is also shared by the protectedDialerControl HTTP clients (registry, OIDC discovery, token introspection) and the skills git-clone host check (pkg/skills/gitresolver), though those destinations are operator-/user-configured rather than attacker-controlled. (Note: the webhook client is *not* affected — it enforces only the HTTPS scheme via ValidatingTransport and performs no IP-based check.)
Details
pkg/networking/utilities.go builds a privateIPBlocks table and IsPrivateIP:
func init() {
for _, cidr := range []string{
"127.0.0.0/8", "10.0.0.0/8", "172.16.0.0/12", "192.168.0.0/16",
"169.254.0.0/16", "::1/128"
Details
Original advisory: https://github.com/advisories/GHSA-pph6-vfjv-vpjw
Referenced CVEs
| CVE | CSIRTS overview | External |
|---|---|---|
| CVE-2026-54450 | coverage & exploitation status | NVD · CVE.org |
More from GitHub Security Advisories
- mediumGHSA-jr6p-8pjj-mfx6: Capsule has an incomplete fix of CVE-2026-22872: TenantResource RawItems and Generators s…2026-07-31
- mediumGHSA-68cj-mvg9-rgm2: Capsule: CapsuleConfiguration NodeMetadata regex fields lack webhook validation, allowing…2026-07-31
- mediumGHSA-ff84-5f28-78qj: re2: Out-of-bounds heap read in `exec`/`test`/`match` via attacker-influenced `lastIndex`…2026-07-31
- mediumGHSA-6hxr-mr5r-9836: re2: Global `String.prototype.match` with an empty-matchable pattern never advances → inf…2026-07-31
- mediumGHSA-x83g-979r-f5fh: Sylius Mollie Plugin has unauthenticated IDOR that leaks order token and customer PII2026-07-31