Guzzle is a popular open-source HTTP client library for PHP. This handy tool lets developers send HTTP requests effortlessly, making it an everyday dependency in Laravel, Symfony, and various other PHP projects. However, a critical vulnerability tagged as CVE-2022-31043 could put your API secrets and user credentials at risk.

In this post, I’ll explain what this vulnerability is, show you how it works in code, and tell you how to fix or work around it. Stay with me—this bug is easy to understand and patch, but leaving it unattended could mean serious trouble.

What Is CVE-2022-31043?

Summary:  
The vulnerability affects Guzzle HTTP client versions before 7.4.4 and 6.5.7. If your app makes HTTPS requests (e.g. to an API with an Authorization header) and the server responds with a redirect to an HTTP URL, Guzzle will *forward* your sensitive Authorization header to the next endpoint—even though it is now cleartext HTTP.

To say it plainly:

Guzzle, in older versions, sends your secret headers along, exposing them on the network.

This is risky, especially when dealing with OAuth tokens, API keys, session cookies, or other auth mechanisms.

More on the original advisory:  
- Guzzle CVE-2022-31043 GitHub Security Advisory
- NVD CVE-2022-31043 Details

Let’s see a quick illustration in code.

use GuzzleHttp\Client;

$client = new Client();

$response = $client->request('GET', 'https://secure.example.com/';, [
    'headers' => [
        'Authorization' => 'Bearer SECRET_TOKEN'
    ]
]);
// If secure.example.com responds with: Location: http://malicious.com/
// ...Guzzle would (before the fix) send 'Authorization: Bearer SECRET_TOKEN' to http://malicious.com/

> Note: The expected safe behavior is *not* to forward auth headers from HTTPS → HTTP, just like it already doesn't forward on host changes.

What could an attacker do?

If a malicious or compromised server (or even a man-in-the-middle) responds with that HTTP redirect, your token or secret header goes out in the open—ready to be snatched, reused, or abused.

Guzzle 6 users: All before 6.5.7

If you’re using older Guzzle versions, you need to update as soon as possible.

Authorization headers are not forwarded across HTTPS→HTTP downgrades.

To patch:

In your project root, run

composer update guzzlehttp/guzzle

Or specify the safe version

composer require guzzlehttp/guzzle:^7.4.4

1. Use a Custom Redirect Middleware

You can write a middleware to strip sensitive headers on redirect, or use one of several community solutions from Guzzle’s middleware docs.

Example custom Middleware

use GuzzleHttp\Middleware;
use Psr\Http\Message\RequestInterface;
use Psr\Http\Message\ResponseInterface;

$removeAuthOnDowngrade = Middleware::mapRequest(function (RequestInterface $request) {
    $redirected = $request->getHeaderLine('Referer') && 
                  parse_url($request->getHeaderLine('Referer'), PHP_URL_SCHEME) === 'https' && 
                  $request->getUri()->getScheme() === 'http';

    if ($redirected) {
        return $request->withoutHeader('Authorization');
    }
    return $request;
});

$stack = \GuzzleHttp\HandlerStack::create();
$stack->push($removeAuthOnDowngrade);

$client = new \GuzzleHttp\Client(['handler' => $stack]);


> *(Note: This is a simplified example. Consider more robust checks for production use.)*

If your application doesn’t rely on redirects, simply *turn them off*. Here’s the option

$client = new \GuzzleHttp\Client([
    'allow_redirects' => false,
]);

Try making an HTTPS request with an Authorization header to an endpoint you control.

2. Have this endpoint reply with a 302 Location: http://yourhttpendpoint/

Conclusion

CVE-2022-31043 is a straightforward but dangerous bug in Guzzle. Any app that makes authenticated HTTPS calls and follows redirects is potentially exposed.

Further reading

- Official Guzzle Fix PR
- Original Disclosure

Stay safe—update your dependencies and keep those tokens secret!

Timeline

Published on: 06/10/2022 00:15:00 UTC
Last modified on: 06/17/2022 15:22:00 UTC