CVEReports
CVEReports

Automated vulnerability intelligence platform. Comprehensive reports for high-severity CVEs generated by AI.

Product

  • Home
  • Sitemap
  • RSS Feed

Company

  • About
  • Contact
  • Privacy Policy
  • Terms of Service

© 2026 CVEReports. All rights reserved.

Made with love by Amit Schendel & Alon Barad



GHSA-H95V-H523-3MW8

GHSA-H95V-H523-3MW8: Sensitive URI Fragment Disclosure via Referer Headers in Guzzle HTTP Client

Amit Schendel
Amit Schendel
Senior Security Researcher

Jul 21, 2026·6 min read·6 visits

Executive Summary (TL;DR)

Guzzle HTTP client leaks client-side URI fragments containing sensitive data (like access tokens) in Referer headers when auto-redirects are configured with referer tracking enabled.

An issue in Guzzle's RedirectMiddleware allows client-side URI fragments to be leaked over the network in Referer headers during same-scheme HTTP redirects.

Vulnerability Overview

The vulnerability resides within the Guzzle HTTP client's redirect handling component, specifically GuzzleHttp\Psr7 and the GuzzleHttp\Middleware\RedirectMiddleware class. Guzzle is a highly popular PHP HTTP client widely used in modern web applications to coordinate integrations and third-party API interactions. Under certain circumstances, configurations that automate redirect processing can expose sensitive client-side data over the network.\n\nWhen a developer explicitly configures the Guzzle client to automatically generate and forward the Referer header during HTTP redirects, the underlying middleware attempts to reconstruct the request's origin context. However, versions of the Guzzle library prior to 7.15.1 fail to validate the structure of the origin URI, enabling client-side fragment data to be serialized and processed over the network. This behavior directly expands the attack surface to include third-party services that receive these redirected request headers.\n\nThe vulnerability class corresponds to CWE-201 (Insertion of Sensitive Information Into Sent Data), stemming from an incorrect abstraction of URI boundaries. Standard web specifications indicate that URI fragments must never traverse the network. By violating this protocol, Guzzle transmits client-side processing states, such as OAuth tokens or single-sign-on hashes, directly to unauthorized network end-points during same-scheme redirections.

Root Cause Analysis

To understand the technical root cause, we must evaluate the distinction between a URI's query parameters and its fragment components. According to RFC 3986 Section 3.5, the fragment identifier contains client-side instructions that identify a secondary resource. Traditional user agents, such as modern web browsers, separate the fragment component from the target URI before executing any HTTP request over the network. Guzzle, as a programmatic HTTP client, implements PSR-7 standards where the entire URI is held in memory as an instance of UriInterface.\n\nWhen Guzzle's RedirectMiddleware intercepts an HTTP 3xx redirect response, it checks if same-scheme redirection is occurring (for instance, redirecting from one HTTPS endpoint to another HTTPS endpoint). If the 'allow_redirects' configuration has 'referer' tracking enabled, Guzzle programmatically builds a new Referer header. It extracts the original request's URI object and attempts to clean it before adding it to the headers array.\n\nThe structural failure in Guzzle's sanitization process is that it only strips the user credentials (username and password) via the withUserInfo('') method. The middleware does not attempt to purge the fragment component. Consequently, the original URI is cast directly to a string, causing Guzzle to serialize the client-side fragment and send it to the destination server in the Referer header.

Code Analysis

Analyzing the source code of Guzzle's RedirectMiddleware.php reveals the precise implementation bug. In vulnerable versions, the middleware validates that same-scheme redirects are occurring prior to constructing the Referer header, but it lacks any logical checks to purge the fragment data.\n\nBelow is the code comparison between the vulnerable and patched implementations of the modifyRequest function within Guzzle's RedirectMiddleware class:\n\nphp\\n// Vulnerable Implementation (Guzzle < 7.15.1)\\nif ($options['allow_redirects']['referer']\\n && $modify['uri']->getScheme() === $request->getUri()->getScheme()\\n) {\\n // Only user info is stripped; the URI fragment is retained\\n $uri = $request->getUri()->withUserInfo('');\\n $modify['set_headers']['Referer'] = (string) $uri;\\n} else {\\n $modify['remove_headers'][] = 'Referer';\\n}\\n\\n// Patched Implementation (Guzzle >= 7.15.1)\\nif ($options['allow_redirects']['referer']\\n && $modify['uri']->getScheme() === $request->getUri()->getScheme()\\n) {\\n // Both user info and fragment are explicitly stripped\\n $uri = $request->getUri()->withUserInfo('')->withFragment('');\\n $modify['set_headers']['Referer'] = (string) $uri;\\n} else {\\n $modify['remove_headers'][] = 'Referer';\\n}\\n\n\nThe patch resolves this by appending the withFragment('') call to the method chain. This returns a cloned UriInterface instance with the fragment property set to an empty string. However, security researchers should observe that query parameters are not stripped. If Guzzle initiates a redirect to a cross-origin server, any sensitive data held in query parameters (such as ?api_key=SECRET) will still be transmitted because Guzzle only validates that the redirect target's scheme matches the source scheme, leaving further domain validation to the developer.

Exploitation & Threat Modeling

An attacker seeking to exploit this vulnerability must target an application that communicates with a service that handles secrets inside URI fragments, such as an OAuth 2.0 authorization server using the implicit grant flow. The client must also have Guzzle's referer-tracking redirect behavior explicitly configured. The attacker must control the destination of a redirect, either via an open redirect flaw on the trusted host or by directly manipulating the client to follow a link to an attacker-controlled server.\n\nWhen the Guzzle client issues a request containing a fragment and the trusted endpoint responds with a 302 Redirect to the attacker's server, Guzzle automatically generates the Referer header. It retains the fragment in the Referer header, sending it to the attacker's host. The attacker then parses their server's access logs to extract the secret.\n\nmermaid\\ngraph LR\\n Client[\"Guzzle Client\\n'allow_redirects.referer' => true\"] -->|\"1. GET /callback#token=SECRET\"| Trusted[\"Trusted Host\\n(trusted-api.com)\"]\\n Trusted -->|\"2. 302 Redirect\\nLocation: https://evil.com/logger\"| Client\\n Client -->|\"3. GET /logger\\nReferer: https://trusted-api.com/callback#token=SECRET\"| Attacker[\"Attacker Server\\n(evil.com)\"]\\n\n\nNo weaponized exploit tools are currently documented in the wild. However, test assertions in Guzzle's test suite confirm that the fragment is transmitted when this code path is traversed under vulnerable configurations.

Impact Assessment

The impact of this vulnerability is a high-risk disclosure of confidential secrets. If an application utilizes fragments to pass temporary authorization keys, single-sign-on parameters, or OAuth state tokens, these values are immediately exposed to any external host that receives a redirect from the client.\n\nAn attacker obtaining these tokens can perform session hijacking, impersonate the application user, or access private application-programming interfaces. The vulnerability has a CVSS v3.1 base score of 5.9, reflecting a high confidentiality impact, with low complexity and no privileges required, balanced by the configuration prerequisites.\n\nBecause this vulnerability has no assigned CVE ID, it is not listed in the CISA KEV catalog, and EPSS scores are not calculated. Nevertheless, the lack of a formal CVE does not diminish the potential severity for systems using insecure redirect configurations.

Remediation & Defensive Engineering

The primary remediation path is upgrading the guzzlehttp/guzzle package to version 7.15.1 or later. The security release replaces the vulnerable code path and guarantees that all URI fragments are stripped prior to Referer header serialization.\n\nIf upgrading the library is not immediately possible, you should verify that Guzzle's referer tracking is disabled. This is Guzzle's default behavior. Ensure that any client instantiations do not explicitly enable this parameter, or explicitly configure it to false as shown below:\n\nphp\\n$client->request('GET', $uri, [\\n 'allow_redirects' => [\\n 'referer' => false, // Explicitly disabled\\n ],\\n]);\\n\n\nDevelopers can also manually sanitize incoming URIs by utilizing PSR-7 methods to strip fragments before executing requests. For example, calling $cleanUri = $uri->withFragment(''); guarantees that the client never processes or forwards client-side data over the network.

Official Patches

GuzzleOfficial GitHub Security Advisory
GuzzleFix Pull Request

Fix Analysis (1)

Technical Appendix

CVSS Score
5.9/ 10
CVSS:3.1/AV:N/AC:H/PR:N/UI:N/S:U/C:H/I:N/A:N

Affected Systems

guzzlehttp/guzzle

Affected Versions Detail

Product
Affected Versions
Fixed Version
guzzlehttp/guzzle
Guzzle
< 7.15.17.15.1
AttributeDetail
CWE IDCWE-201
Attack VectorNetwork (AV:N)
CVSS Score5.9 (Medium)
Exploit StatusNone/Unproven
EPSS ScoreN/A
CISA KEV StatusNot Listed
ImpactInformation Disclosure

MITRE ATT&CK Mapping

T1552.001Credentials in Files / Client-Side State
Credential Access
T1557Adversary-in-the-Middle
Credential Access
CWE-201
Insertion of Sensitive Information Into Sent Data

The product inserts sensitive information into a record or data flow that is sent to another actor.

Vulnerability Timeline

Guzzle version 7.15.0 released
2026-07-17
Security patch commit pushed to GitHub
2026-07-18
Guzzle version 7.15.1 released and security advisory published
2026-07-20

References & Sources

  • [1]GitHub Advisory GHSA-H95V-H523-3MW8
  • [2]Fix Commit
  • [3]RFC 9110 Section 10.1.3
  • [4]RFC 3986 Section 3.5
  • [5]RFC 9700 Section 4.2.3

Attack Flow Diagram

Press enter or space to select a node. You can then use the arrow keys to move the node around. Press delete to remove it and escape to cancel.
Press enter or space to select an edge. You can then press delete to remove it or escape to cancel.

More Reports

•14 minutes ago•CVE-2026-59198
6.5

CVE-2026-59198: Heap Out-of-Bounds Read in Pillow TGA RLE Encoder

CVE-2026-59198 is a high-severity heap out-of-bounds read vulnerability in Pillow, the Python imaging library, affecting versions from 5.2.0 up to 12.3.0. The vulnerability occurs in the TGA RLE compression path due to a calculation mismatch between the allocated packed 1-bit row buffer and the byte-level pixel stride assumption in the C-level encoder. This mismatch allows an attacker to leak up to approximately 57 KB of adjacent process heap memory directly into generated TGA image files.

Alon Barad
Alon Barad
0 views•8 min read
•about 1 hour ago•CVE-2026-59199
7.5

CVE-2026-59199: Signed 32-Bit Integer Overflow and Heap Backward Underwrite in Pillow

A critical signed 32-bit integer overflow vulnerability was identified in Pillow (Python Imaging Library) versions prior to 12.3.0. The vulnerability resides within the native C extension library (libImaging) during coordinate and bounding box calculations in functions like ImagingPaste and ImagingFill2. Exploitation can bypass bounds and clipping safety checks, leading to a controlled heap backward underwrite and application crash.

Alon Barad
Alon Barad
4 views•6 min read
•about 2 hours ago•CVE-2026-59200
7.5

CVE-2026-59200: Remote Denial of Service via PDF Decompression Bomb in Pillow

CVE-2026-59200 is a high-severity uncontrolled resource consumption vulnerability in the Pillow Python Imaging Library. The flaw resides in the PDF stream decoder, allowing remote, unauthenticated attackers to trigger host out-of-memory crashes by submitting malicious PDF decompression bombs.

Alon Barad
Alon Barad
4 views•5 min read
•about 3 hours ago•CVE-2026-59203
5.3

CVE-2026-59203: Denial of Service via Infinite Loop in Pillow EPS Image Parser

A denial-of-service (DoS) vulnerability in Pillow (Python Imaging Library) versions 12.0.0 through 12.2.0 allows unauthenticated remote attackers to trigger 100% CPU utilization and hang the processing thread. The issue occurs within the Encapsulated PostScript (EPS) image parser (PIL/EpsImagePlugin.py) due to missing validation on the byte count parsed from %%BeginBinary: comments, allowing negative values to cause an infinite backward stream seek loop. This formatting-level state-looping issue occurs during the initial format sniffing phase inside Image.open() and does not require the system Ghostscript interpreter to be executed or present. It is resolved in version 12.3.0.

Amit Schendel
Amit Schendel
4 views•6 min read
•about 4 hours ago•CVE-2026-59204
7.5

CVE-2026-59204: Denial of Service via Memory Exhaustion in Pillow JPEG2000 Decoder

A Denial of Service vulnerability exists in the JPEG2000 decoder of Pillow (versions 8.2.0 to 12.2.0) due to memory allocation state accumulation across tiles, leading to rapid process termination.

Amit Schendel
Amit Schendel
8 views•7 min read
•about 5 hours ago•CVE-2026-59205
7.5

CVE-2026-59205: Heap-Based Buffer Overflow in Pillow ImageCms Module

CVE-2026-59205 is a high-severity heap-based out-of-bounds write vulnerability affecting Pillow prior to version 12.3.0. The flaw stems from a validation omission in the ImageCmsTransform class where source and destination image modes are not checked against the configurations defined during the creation of the transform. An attacker can exploit this discrepancy to trigger a heap buffer overflow or an out-of-bounds read by supplying an under-allocated target image buffer.

Amit Schendel
Amit Schendel
7 views•5 min read