Gotenberg CVE-2026-45741
HIGHCVSS VectorNVD
CVSS:3.1/AV:N/AC:H/PR:N/UI:N/S:C/C:H/I:L/A:N
Lifecycle Timeline
3DescriptionNVD
Summary
IsPublicIP in pkg/gotenberg/outbound.go incorrectly classifies IPv6 6to4 / NAT64 / deprecated site-local addresses as public IPs, allowing an unauthenticated attacker to reach internal destinations (e.g., cloud metadata services at 169.254.169.254) via a single crafted DNS AAAA record. This is a variant of CVE-2026-44430 (modelcontextprotocol/registry).
Details
IsPublicIP uses Go stdlib helpers (IsLoopback, IsPrivate, IsLinkLocalUnicast, etc.) to block internal IPs. However, these helpers do not recognize IPv6 prefixes that embed IPv4 addresses:
| Prefix | RFC | Tunnels to |
|---|---|---|
2002::/16 | RFC 3056 (6to4) | IPv4 in bits 16-47 |
64:ff9b::/96 | RFC 6052 (NAT64 well-known) | IPv4 in low 32 bits |
64:ff9b:1::/48 | RFC 8215 (NAT64 local-use) | IPv4 in low 32 bits |
fec0::/10 | RFC 3879 (deprecated site-local) | internal routing |
addr.Unmap() only handles ::ffff:0:0/96 (IPv4-mapped) and has no effect on these prefixes. On dual-stack or NAT64-enabled cloud hosts, the OS kernel transparently routes these addresses to their embedded internal IPv4 destinations.
Vulnerable code (pkg/gotenberg/outbound.go L53-69, commit 93d0103):
func IsPublicIP(addr netip.Addr) bool {
addr = addr.Unmap() // only handles ::ffff:x.x.x.x
switch {
case addr.IsLoopback(), addr.IsPrivate(),
addr.IsLinkLocalUnicast(), ...:
return false
}
return true // 6to4/NAT64/site-local incorrectly reaches here
}PoC
cd poc/
./build.sh
# docker build (~30s)
./run.sh
# docker run - exits with code 1 (bug detected)Expected output: IsPublicIP(2002:a9fe:a9fe::) = true - the function returns true for 3 addresses that wrap 169.254.169.254 (AWS IMDS). Full test file available via GHSA private comment on request.
Impact
An unauthenticated attacker controlling a DNS AAAA record can tunnel gotenberg's outbound HTTP client to AWS/GCP/Azure IMDS (169.254.169.254), leaking IAM credentials. The Chromium URL convert route returns the full response as a PDF (full-read SSRF). Affects all deployments with WithDenyPrivateIPs(true) on dual-stack or NAT64-enabled hosts.
Suggested Fix
Add explicit prefix checks after addr.Unmap():
var blockedIPv6Prefixes = []netip.Prefix{
netip.MustParsePrefix("2002::/16"),
netip.MustParsePrefix("64:ff9b::/96"),
netip.MustParsePrefix("64:ff9b:1::/48"),
netip.MustParsePrefix("fec0::/10"),
}
for _, p := range blockedIPv6Prefixes {
if p.Contains(addr) { return false }
}AnalysisAI
SSRF deny-list bypass in Gotenberg v8 (<= 8.32.0) allows unauthenticated remote attackers to reach internal cloud metadata services (e.g., AWS/GCP/Azure IMDS at 169.254.169.254) by serving a crafted DNS AAAA record containing IPv6 6to4, NAT64, or deprecated site-local prefixes that the IsPublicIP allow-list fails to recognize. Publicly available exploit code exists via the GitHub Security Advisory PoC, and the Chromium URL-convert route returns the upstream response as a PDF, yielding a full-read SSRF that can leak IAM credentials. …
Sign in for full analysis, threat intelligence, and remediation guidance.
RemediationAI
Within 24 hours: Scan all systems to identify Gotenberg v8 instances at version 8.32.0 or earlier and document their deployment context and network connectivity to cloud environments. Within 7 days: Implement network-level egress filtering to block access from Gotenberg processes to 169.254.169.254/32 (cloud metadata endpoints) and deploy Web Application Firewall rules to detect IPv6 6to4, NAT64, and site-local prefix patterns in requests. …
Sign in for detailed remediation steps.
More from same product – last 7 days
{filename} endpoint. The flawed traversal guard only rejects forward slashes and '..' sequences, so absolute Windows pat
Sandbox escape in Google Chrome on Android prior to 148.0.7778.216 allows remote attackers to corrupt GPU process memory
Sandbox escape in Google Chrome versions prior to 148.0.7778.216 allows a remote attacker to exploit a use-after-free co
Sandbox escape in Google Chrome on macOS prior to 148.0.7778.216 allows a remote attacker to break out of the renderer s
Sandbox escape in Google Chrome versions prior to 148.0.7778.216 allows a remote attacker to break out of the renderer s
Share
External POC / Exploit Code
Leaving vuln.today
GHSA-86m8-88fq-xfxp