Failure to strip the Cookie header on change in host or HTTP downgrade in Guzzle
Description
Guzzle is an open source PHP HTTP client. In affected versions the Cookie headers on requests are sensitive information. On making a request using the https scheme to a server which responds with a redirect to a URI with the http scheme, or on making a request to a server which responds with a redirect to a a URI to a different host, we should not forward the Cookie header on. Prior to this fix, only cookies that were managed by our cookie middleware would be safely removed, and any Cookie header manually added to the initial request would not be stripped. We now always strip it, and allow the cookie middleware to re-add any cookies that it deems should be there. Affected Guzzle 7 users should upgrade to Guzzle 7.4.4 as soon as possible. Affected users using any earlier series of Guzzle should upgrade to Guzzle 6.5.7 or 7.4.4. Users unable to upgrade may consider an alternative approach to use your own redirect middleware, rather than ours. If you do not require or expect redirects to be followed, one should simply disable redirects all together.
AI Insight
LLM-synthesized narrative grounded in this CVE's description and references.
Guzzle PHP HTTP client fails to strip manually added Cookie headers during cross-scheme or cross-host redirects, leaking sensitive cookies.
Vulnerability
Description
CVE-2022-31042 is a cookie forwarding vulnerability in the Guzzle PHP HTTP client. When Guzzle follows a redirect from an HTTPS URI to an HTTP URI, or to a different host, the HTTP specification (RFC 9110) mandates that sensitive headers like Cookie must not be forwarded to the new target [1]. Prior to the fix, Guzzle only removed cookies managed by its internal cookie middleware; any Cookie header that a user manually added to the initial request would be forwarded without stripping, violating the standard [2].
Attack
Vector
The vulnerability arises during HTTP redirect following. An attacker who can control the redirect target (e.g., by conducting a man-in-the-middle attack, hosting a malicious server, or exploiting an open redirect on a legitimate server) can cause a Guzzle client to leak manually attached Cookie headers. The attack does not require authentication against the client; it only requires that the client follows a redirect to an insecure scheme or a different host. No special network position beyond being able to intercept or redirect HTTP traffic is needed.
Impact
An attacker can obtain sensitive cookies (e.g., session tokens, authentication credentials) that were manually added to the initial request. This could lead to session hijacking, account takeover, or unauthorized access to protected resources. The Guzzle project considers Cookie headers to be sensitive information and recommends immediate patching [2][4].
Mitigation
The vulnerability is fixed in Guzzle versions 7.4.4 and 6.5.7 [2]. Users of Guzzle 7 should upgrade to 7.4.4; users of earlier series should upgrade to 6.5.7 or 7.4.4. Users unable to upgrade can either implement a custom redirect middleware that properly strips Cookie headers, or disable redirect handling entirely if redirects are not required [2][4].
AI Insight generated on May 21, 2026. Synthesized from this CVE's description and the cited reference URLs; citations are validated against the source bundle.
Affected packages
Versions sourced from the GitHub Security Advisory.
| Package | Affected versions | Patched versions |
|---|---|---|
guzzlehttp/guzzlePackagist | >= 4.0.0, < 6.5.7 | 6.5.7 |
guzzlehttp/guzzlePackagist | >= 7.0.0, < 7.4.4 | 7.4.4 |
Affected products
3- osv-coords2 versions
>= 9.2.0, < 9.2.21+ 1 more
- (no CPE)range: >= 9.2.0, < 9.2.21
- (no CPE)range: >= 4.0.0, < 6.5.7
- guzzle/guzzlev5Range: < 6.5.7
Patches
13 files changed · +63 −12
CHANGELOG.md+5 −0 modified@@ -2,6 +2,11 @@ Please refer to [UPGRADING](UPGRADING.md) guide for upgrading to a major version. +## 7.4.4 - 2022-06-09 + +* Fix failure to strip Authorization header on HTTP downgrade +* Fix failure to strip the Cookie header on change in host or HTTP downgrade + ## 7.4.3 - 2022-05-25 * Fix cross-domain cookie leakage
src/RedirectMiddleware.php+34 −7 modified@@ -142,7 +142,7 @@ static function (ResponseInterface $response) use ($uri, $statusCode) { } /** - * Check for too many redirects + * Check for too many redirects. * * @throws TooManyRedirectsException Too many redirects. */ @@ -178,7 +178,7 @@ public function modifyRequest(RequestInterface $request, array $options, Respons $modify['body'] = ''; } - $uri = $this->redirectUri($request, $response, $protocols); + $uri = self::redirectUri($request, $response, $protocols); if (isset($options['idn_conversion']) && ($options['idn_conversion'] !== false)) { $idnOptions = ($options['idn_conversion'] === true) ? \IDNA_DEFAULT : $options['idn_conversion']; $uri = Utils::idnUriConvert($uri, $idnOptions); @@ -198,19 +198,46 @@ public function modifyRequest(RequestInterface $request, array $options, Respons $modify['remove_headers'][] = 'Referer'; } - // Remove Authorization header if host is different. - if ($request->getUri()->getHost() !== $modify['uri']->getHost()) { + // Remove Authorization and Cookie headers if required. + if (self::shouldStripSensitiveHeaders($request->getUri(), $modify['uri'])) { $modify['remove_headers'][] = 'Authorization'; + $modify['remove_headers'][] = 'Cookie'; } return Psr7\Utils::modifyRequest($request, $modify); } /** - * Set the appropriate URL on the request based on the location header + * Determine if we should strip sensitive headers from the request. + * + * We return true if either of the following conditions are true: + * + * 1. the host is different; + * 2. the scheme has changed, and now is non-https. */ - private function redirectUri(RequestInterface $request, ResponseInterface $response, array $protocols): UriInterface - { + private static function shouldStripSensitiveHeaders( + UriInterface $originalUri, + UriInterface $modifiedUri + ): bool { + if (\strcasecmp($originalUri->getHost(), $modifiedUri->getHost()) !== 0) { + return true; + } + + if ($originalUri->getScheme() !== $modifiedUri->getScheme() && 'https' !== $modifiedUri->getScheme()) { + return true; + } + + return false; + } + + /** + * Set the appropriate URL on the request based on the location header. + */ + private static function redirectUri( + RequestInterface $request, + ResponseInterface $response, + array $protocols + ): UriInterface { $location = Psr7\UriResolver::resolve( $request->getUri(), new Psr7\Uri($response->getHeaderLine('Location'))
tests/RedirectMiddlewareTest.php+24 −5 modified@@ -272,18 +272,37 @@ public function testInvokesOnRedirectForRedirects() self::assertTrue($call); } - public function testRemoveAuthorizationHeaderOnRedirect() + public function crossOriginRedirectProvider() + { + return [ + ['http://example.com?a=b', 'http://test.com/', false], + ['https://example.com?a=b', 'https://test.com/', false], + ['http://example.com?a=b', 'https://test.com/', false], + ['https://example.com?a=b', 'http://test.com/', false], + ['http://example.com?a=b', 'http://example.com/', true], + ['https://example.com?a=b', 'https://example.com/', true], + ['http://example.com?a=b', 'https://example.com/', true], + ['https://example.com?a=b', 'http://example.com/', false], + ]; + } + + /** + * @dataProvider crossOriginRedirectProvider + */ + public function testHeadersTreatmentOnRedirect($originalUri, $targetUri, $shouldBePresent) { $mock = new MockHandler([ - new Response(302, ['Location' => 'http://test.com']), - static function (RequestInterface $request) { - self::assertFalse($request->hasHeader('Authorization')); + new Response(302, ['Location' => $targetUri]), + static function (RequestInterface $request) use ($shouldBePresent) { + self::assertSame($shouldBePresent, $request->hasHeader('Authorization')); + self::assertSame($shouldBePresent, $request->hasHeader('Cookie')); + return new Response(200); } ]); $handler = HandlerStack::create($mock); $client = new Client(['handler' => $handler]); - $client->get('http://example.com?a=b', ['auth' => ['testuser', 'testpass']]); + $client->get($originalUri, ['auth' => ['testuser', 'testpass'], 'headers' => ['Cookie' => 'foo=bar']]); } public function testNotRemoveAuthorizationHeaderOnRedirect()
Vulnerability mechanics
Generated on May 9, 2026. Inputs: CWE entries + fix-commit diffs from this CVE's patches. Citations validated against bundle.
References
8- github.com/advisories/GHSA-f2wf-25xc-69c9ghsaADVISORY
- nvd.nist.gov/vuln/detail/CVE-2022-31042ghsaADVISORY
- www.debian.org/security/2022/dsa-5246ghsavendor-advisoryWEB
- github.com/FriendsOfPHP/security-advisories/blob/master/guzzlehttp/guzzle/CVE-2022-31042.yamlghsaWEB
- github.com/guzzle/guzzle/commit/e3ff079b22820c2029d4c2a87796b6a0b8716ad8ghsaWEB
- github.com/guzzle/guzzle/security/advisories/GHSA-f2wf-25xc-69c9ghsaWEB
- www.drupal.org/sa-core-2022-011ghsaWEB
- www.rfc-editor.org/rfc/rfc9110.htmlghsaWEB
News mentions
0No linked articles in our index yet.