CVE-2026-69246 is an SSRF bypass in Guzzle that exploits a semantic gap between how PHP validates host strings and how libcurl parses them. When you validate a URI like http://localhost%2f.. with filter_var or similar checks, you're validating the literal string. But Guzzle hands this string to cURL as-is, and cURL's parser treats %2f as a forward slash—resolving to the actual localhost resource. The validation layer and the transport layer are operating on different representations of the same URI.
What makes this serious is that downstream Guzzle components rely on the same host string for security decisions. The no_proxy configuration (which keeps certain internal hosts from going through a proxy that might log or inspect traffic) uses the literal string for matching. The RedirectMiddleware that strips Authorization and Cookie headers on redirects also operates on the transport's parsed representation. When an attacker uses percent-encoding to bypass your SSRF validation, they're simultaneously rewriting your routing decisions and credential-handling logic—without triggering any of the defenses designed to govern those decisions.
The patch percent-decodes the host before validation, which closes this specific bypass. However, this shifts the semantic contract: applications that validate the literal string and expect Guzzle to preserve it end-to-end may now have inconsistent state between what gets resolved and what appears in the Host header. If you've built validation logic that assumes the original encoding is preserved, you'll need to align it with Guzzle's new behavior.
This pattern isn't unique to Guzzle or PHP. Python's urllib3 (CVE-2021-3737), Node's undici, and Ruby's Net::HTTP have all had the same validation-then-transport divergence. The root cause is architectural: HTTP client libraries hand raw URI strings to transports that have their own parsers, and URI specification permits multiple serializations of the same resource. The fix in any single library doesn't eliminate the underlying assumption that validation and transport can operate on the same string independently.
Monitor your access logs for this pattern: requests that your SSRF defenses logged as blocked but that resulted in internal-network traffic. The bypass leaves no forensic artifact in conventional logging because the divergence happens inside the HTTP client's transport layer.