CVE-2026-55245: Bifrost isPublicIP SSRF Deny-List Bypass via NAT64, 6to4, and CGNAT
Bifrost's AI gateway will fetch internal URLs it should block, including the cloud instance-metadata endpoint, because its IP allow/deny classifier misses CGNAT, IPv6 6to4, NAT64, and deprecated…

The problem
The isPublicIP function in core/providers/utils/fetch.go is the sole network guard for FetchAndEncodeURL, which fetches remote image and document URLs in multimodal Bedrock and Vertex requests.
Go's addr.IsPrivate() only covers RFC 1918 and RFC 4193 (fc00::/7). It does not cover CGNAT (100.64.0.0/10). addr.Unmap() collapses the ::ffff:0:0/96 IPv4-mapped form only, so 6to4 (2002::/16) and NAT64 (64:ff9b::/96, 64:ff9b:1::/48) representations of internal IPv4 are never reduced before classification and slip through.
Deprecated IPv6 site-local (fec0::/10) is also missed. Any client that can send a multimodal chat-completion request can choose the fetch target.
Proof of concept
A working proof-of-concept for CVE-2026-55245 in github.com/maximhq/bifrost/core, with the exact payload below.
POST /v1/chat/completions HTTP/1.1
Host: bifrost-gateway
Content-Type: application/json
{
"model": "anthropic.claude-3-5-sonnet-20241022-v2:0",
"messages": [
{
"role": "user",
"content": [
{
"type": "image_url",
"image_url": {
"url": "http://[64:ff9b::a9fe:a9fe]/latest/meta-data/iam/security-credentials/"
}
},
{ "type": "text", "text": "describe this" }
]
}
]
}The NAT64 well-known prefix 64:ff9b::/96 embeds an IPv4 address in its low 32 bits. a9fe:a9fe decodes to 169.254.169.254, the cloud IMDS endpoint. Because isPublicIP calls only addr.Unmap() (which handles ::ffff:0:0/96 only) and then checks IsLoopback, IsPrivate, IsLinkLocalUnicast, etc., the NAT64 form is never reduced to its embedded IPv4, so all those checks pass and the function returns true (public, allowed).
The 6to4 form 2002:a9fe:a9fe:: embeds the same 169.254.169.254 in bytes 2-5 and is also never decoded. CGNAT 100.64.0.0/10 is not RFC 1918 and not covered by IsPrivate, so it is also admitted. The PoC shows gateBlock=false with actual dial attempts (EOF or timeout) for all four bypass families, versus gateBlock=true (no socket opened) for every control.
CWE-918.
The fix
Upgrade github.com/maximhq/bifrost/core to v1.5.17 (commit 54ec431fc5255ff42c36420d88549477e0b33d89, PR #4092). The fix extends isPublicIP to explicitly reject 100.64.0.0/10 (CGNAT), extract and re-classify embedded IPv4 from 6to4 (2002::/16) and NAT64 (64:ff9b::/96, 64:ff9b:1::/48) prefixes, and reject deprecated site-local fec0::/10.
Related research
- critical · 9.3CVE-2026-73080CVE-2026-73080: SeaweedFS Unauthenticated SSRF via VolumeServer.FetchAndWriteNeedle
- critical · 9.6CVE-2026-54725CVE-2026-54725: vault-secrets-webhook Annotation SSRF and ServiceAccount Token Theft
- critical · 10CVE-2026-54735CVE-2026-54735: prebid-server Bidder Adapter Server-Side Request Forgery
- high · 7.7CVE-2026-58314CVE-2026-58314: Gitea SSRF via Incomplete IP Classifier and Unguarded OpenID Discovery