Aug 4, 2026·7 min read·33 visits
Guzzle's cookie matching logic failed to identify noncanonical IPv4 host formats (like hexadecimal, octal, or percent-encoded) as IP literals, incorrectly applying standard suffix/subdomain matching and leaking sensitive cookies to attacker-controlled subdomains.
A vulnerability in the Guzzle HTTP client allows session identifiers, auth tokens, or cookies to be leaked to unauthorized hosts due to incorrect cookie domain validation of noncanonical IPv4 host formats. Guzzle failed to recognize octal, hexadecimal, and percent-encoded IP addresses as IP literals, treating them as standard domains and incorrectly extending their scope to subdomains.
The Guzzle HTTP client is a standard library used in PHP web applications to perform HTTP requests. A critical responsibility of any HTTP client with cookie management enabled (a Cookie Jar) is the isolation of sensitive state across origin boundaries. When managing session cookies, client-side libraries must adhere strictly to domain matching specifications to ensure cookies set by one domain are not transmitted to untrusted hosts.
The vulnerability identified as CVE-2026-69245 belongs to the CWE-180 (Incorrect Behavior Order: Validate Before Canonicalize) and CWE-346 (Origin Validation Error) classes. It represents a systematic failure in how Guzzle handles the scopes of domains that are actually IP address literals or numeric hosts. Standard cookies set for an IP address must never be matched against subdomains, because numeric IP addresses do not have hierarchical subdomains.
Prior to the patches, Guzzle's cookie domain matching routine incorrectly recognized noncanonical IPv4 host representations, such as hexadecimal or octal encodings, as valid domain suffixes rather than IP literals. Consequently, when Guzzle processed an outbound request to an attacker-controlled subdomain appended to a noncanonical IP string, it incorrectly attached cookies associated with the IP address. This led to potential cross-subdomain session leaking and cookie injection.
The fundamental security boundary for cookies on numeric IP hosts is defined in RFC 6265, Section 5.1.3. This standard dictates that a cookie's Domain attribute must match the request host exactly if the host is identified as an IP address. Suffix-based matching, which permits standard domains to share cookies with their subdomains (e.g., example.com and sub.example.com), must be disabled when the host is a numeric IP.
In Guzzle's legacy codebase, the verification of whether a host represents an IP literal was confined to a simplistic check in the SetCookie::matchesDomain() function. This code split the host string by dot characters and verified if the final label consisted entirely of digits using PHP's ctype_digit(). While this accurately identified canonical dotted-decimal IPv4 formats (e.g., 127.0.0.1), it was unable to identify noncanonical formats that underlying network transports accept.
Operating system DNS resolvers and standard libraries such as libcurl parse hosts using inet_aton-compatible rules, which accept hexadecimal (e.g., 0x7f000001), octal (e.g., 0177.0.0.1), mixed-base representation, and percent-encoded IP addresses. Because Guzzle's simple digit check did not recognize these alternative string patterns as IP literals, Guzzle fallback-validated the host as a hierarchical domain. An attacker could register or construct a hostname like evil.0x7f000001 which Guzzle's domain matcher would treat as a valid subdomain of the domain 0x7f000001, leading to scope leakage.
To understand the mechanics of the vulnerability, we analyze the structural changes implemented in the Guzzle codebase. Prior to Guzzle 7.15.2 and 8.0.1, the SetCookie::matchesDomain() function determined IP literal status using only basic string separation.
Here is the vulnerable logic inside src/Cookie/SetCookie.php:
// Vulnerable Guzzle code
$labels = \\explode('.', $host);
$last = (string) \\end($labels);
if ($last !== '' && \\ctype_digit($last)) {
// Correctly identifies canonical IPv4, but fails for noncanonical formats
return false; // Prevent suffix matching for canonical IP
}The patch introduces a dedicated validator class and refactors matchesDomain() to reject percent-encoded cookie domains and utilize strict parsing for alternate formats:
// Patched Guzzle code in src/Cookie/SetCookie.php
public function matchesDomain(string $domain): bool
{
// ...
// Reject percent-escaped domains from wildcard matches
if (\\strpos($cookieDomain, '%') !== false) {
return false;
}
// Utilize the new HostValidator to evaluate IP and numeric host formats
if (self::isIpAddressOrNumericHost($cookieDomain)) {
return false;
}
// ...
}
private static function isIpAddressOrNumericHost(string $host): bool
{
$labels = \\explode('.', $host);
$last = (string) \\end($labels);
if ($last !== '' && \\ctype_digit($last)) {
return true;
}
// Evaluate against the transport's decimal, octal, and hexadecimal inet_aton grammar
return HostValidator::isNumericIpv4Host(\\rtrim($host, '.'));
}The introduction of src/Handler/HostValidator.php provides a systematic way to validate request hosts before they reach the transport layer. The function isNumericIpv4Host() splits the incoming host and validates each octet structure. If the octet matches a hex format (e.g., starting with 0x or 0X), it verifies the characters via standard hexadecimal character maps. If it matches octal format (starting with 0), it restricts the character range to octal digits.
Exploitation of this vulnerability requires that an application using Guzzle has enabled a persistent cookie jar and initiates HTTP requests targeting noncanonical representations of an IP address. The attack can proceed in two primary ways: session exfiltration (information disclosure) and session fixation.
In a session exfiltration attack, the target client is directed to make a request to a canonical host represented noncanonically, such as http://0x7f000001/ (resolving to local host). The responding server sets a sensitive cookie with Domain=0x7f000001. Because Guzzle fails to identify the host as an IP, it registers the cookie with suffix-matching capabilities. When the client subsequently makes a request to http://evil.0x7f000001/, Guzzle's domain scope matching incorrectly permits the transmission of the 0x7f000001 cookie to the attacker-controlled server.
In a session fixation scenario, the client is directed to the malicious domain http://evil.0x7f000001/. The attacker's server responds by setting a cookie with Domain=0x7f000001 containing a pre-generated session ID. Guzzle accepts this cookie because it treats 0x7f000001 as a regular top-level domain. When the client subsequently accesses http://0x7f000001/, Guzzle transmits the fixed session identifier, allowing the attacker to intercept and control the session state.
While the patches implemented in versions 7.15.2 and 8.0.1 significantly decrease the attack surface, parser differences between the verification layer and the underlying transport layer may still yield edge-case exploitation pathways.
One potential gap involves IDN-capable transports. Many modern systems compile PHP's Curl extension with support for Internationalized Domain Names (IDN) via libidn2 or similar libraries. If a Guzzle client makes a request to a host using Unicode Fullwidth digits (e.g., 127.0.0.1 where 1 is U+FF11), Guzzle's HostValidator checks for printable ASCII and redirects the URI parsing through the IDN conversion middleware if enabled. If the domain matching routine evaluates the unnormalized host string prior to canonicalization, Guzzle may treat it as a domain name, while the underlying curl transport normalizes and resolves it directly to the IP literal 127.0.0.1.
Another gap is the variation of inet_aton behaviors across target operating systems. While Guzzle's isNumericIpv4Host() strictly parses standard decimal, octal, and hexadecimal formats, certain operating systems handle extreme cases—such as integer overflows in octal fields or single-part integer hosts (e.g., 2130706433 which resolves to 127.0.0.1)—in inconsistent ways. If Guzzle classifies a single-part integer as a regular domain name but the OS resolver translates it to an IP address, cookie scope mismatch can still occur.
Mitigation of CVE-2026-69245 requires upgrading Guzzle dependencies to versions that contain the host validation and strict IP parsing logic. Applications on the Guzzle 7.x release branch must be updated to at least 7.15.2, and applications on the 8.x branch must be updated to at least 8.0.1. These updates are available through standard PHP Composer package installations.
To detect historical or active exploitation attempts at the network proxy or web application firewall layer, security teams can implement regular expressions designed to catch noncanonical IP formats within Host headers. WAF rules should check for hexadecimal patterns like 0x followed by hexadecimal digits within HTTP headers. Additionally, check for octal representations where octets start with a leading zero and are followed exclusively by octal digits 0-7.
At the application level, developers must ensure that any user-supplied IP addresses or host configurations are fully validated using native PHP structures before being passed into Guzzle requests. Using filter_var($host, FILTER_VALIDATE_IP) allows the application to discard noncanonical host strings entirely or normalize them to standard decimal format before Guzzle initiates the HTTP request lifecycle.
CVSS:3.1/AV:N/AC:L/PR:N/UI:N/S:U/C:L/I:L/A:N| Product | Affected Versions | Fixed Version |
|---|---|---|
Guzzle Guzzle | < 7.15.2 | 7.15.2 |
Guzzle Guzzle | >= 8.0.0, < 8.0.1 | 8.0.1 |
| Attribute | Detail |
|---|---|
| CWE ID | CWE-180, CWE-346, CWE-384 |
| Attack Vector | Network (AV:N) |
| Attack Complexity | Low (AC:L) |
| CVSS Severity | 6.5 Medium |
| EPSS Score | Not Available |
| Exploit Status | Proof-of-Concept |
| CISA KEV Status | Not Listed |
The application parses or verifies cookie domains using raw string values before resolving noncanonical representations (e.g., hexadecimal or percent-encoded) which the transport layer subsequently canonicalizes or decodes.
CVE-2026-107718 is a medium-severity Open Redirect vulnerability in the core HTTP server package of the AdonisJS Node.js framework. Prior to versions 8.2.3 and 9.3.0, the framework built route paths by directly interpolating dynamic parameters and wildcard segments without URI encoding. If an application routes attacker-controlled input directly to a dynamic first path segment and uses the generated route URL as a redirect destination, a leading slash can produce a scheme-relative external URL. Modern web browsers process scheme-relative URLs by redirecting the client to the specified external domain, exposing users to credential harvesting, social engineering, and session hijacking. This vulnerability affects all applications running unpatched configurations where input validation is not explicitly implemented before generating paths.
CVE-2026-107725 is a critical security bypass in Hazelcast where missing authorization checks in the MapPermission class permit unprivileged clients to issue queries containing aggregators or projections. This architectural oversight allows attackers to run arbitrary code on the cluster servers under the privileges of the active Hazelcast process.
A stored Cross-Site Scripting (XSS) vulnerability was identified in Indico, an open-source event management system developed at CERN, prior to version 3.3.13. The vulnerability stems from weak URL validation in custom link fields and lack of HTML sanitization during Marshmallow serialization of event notes. This allows authenticated attackers with event modification privileges to inject malicious payloads that execute in the browser of users viewing the event pages or collaborating on notes.
A technical analysis of CVE-2026-107397, a stored Cross-Site Scripting (XSS) vulnerability in Indico's collaborative notes editor and custom link generation fields. Prior to version 3.3.13, Marshmallow serialization schemas omitted HTML sanitization during conflict resolution, and form validators failed to enforce strict URI schemes, enabling authenticated low-privilege attackers to execute arbitrary JavaScript.
An authorization bypass vulnerability exists in the legacy session export API of Indico, an open-source event management system developed at CERN. Due to a missing object-level access check, authenticated users can bypass configuration-level restrictions to extract private session metadata (including session titles, descriptions, and list of conveners) from events that they are otherwise authorized to view.
An incomplete Server-Side Request Forgery (SSRF) validation check in Indico prior to version 3.3.13 allows authenticated event organizers to bypass outbound network restrictions. By utilizing backslash characters within crafted URLs, attackers can exploit a parser differential between the application's validator and the downstream HTTP client library to access internal network resources.