Sensitive header uncleared on same-host, cross-port redirect in guzzle/guzzle

Valid

Reported on

Jun 10th 2022


Description

Sensitive headers are uncleared on cross-port redirect

Proof of Concept

poc.php

<?php                                                                                                                                                      
                                                                                                                                                           
require 'vendor/autoload.php';                                                                                                                             
                                                                                                                                                           
use GuzzleHttp\Client;                                                                                                                                     
                                                                                                                                                           
$client = new Client([                                                                                                                                     
  'base_uri' => 'http://10.0.2.4',                                                                                                                         
]);                                                                                                                                                        
                                                                                                                                                           
$response = $client->get('/redirect.php', [                                                                                                                
  'debug' => TRUE,                                                                                                                                         
  'headers' => [                                                                                                                                           
      'Content-Type' => 'application/x-www-form-urlencoded',                                                                                               
      'Cookie' => 'a=b',                                                                                                                                   
      'Authorization' => 'secret',                                                                                                                         
  ]                                                                                                                                                        
]);                                                                                                                                                        
                                                                                                                                                           
$body = $response->getBody(); 

See that the headers are also sent from port 80 to port 81.

*   Trying 10.0.2.4:80...
* TCP_NODELAY set
* Connected to 10.0.2.4 (10.0.2.4) port 80 (#0)
> GET /redirect.php HTTP/1.1
Host: 10.0.2.4
User-Agent: GuzzleHttp/7
Content-Type: application/x-www-form-urlencoded
Cookie: a=b
Authorization: secret

* Mark bundle as not supporting multiuse
< HTTP/1.1 302 Found
< Date: Fri, 10 Jun 2022 14:58:01 GMT
< Server: Apache/2.4.53 (Debian)
< Location: http://10.0.2.4:81
< Content-Length: 0
< Content-Type: text/html; charset=UTF-8
< 
* Connection #0 to host 10.0.2.4 left intact
*   Trying 10.0.2.4:81...
* TCP_NODELAY set
* Connected to 10.0.2.4 (10.0.2.4) port 81 (#1)
> GET / HTTP/1.1
Host: 10.0.2.4:81
User-Agent: GuzzleHttp/7
Content-Type: application/x-www-form-urlencoded
Cookie: a=b
Authorization: secret

Impact

There are instances where different people control different ports on the same host. So sending sensitive headers to a different port will result in these headers being leaked to 3rd party as well. For reference, curl versions >= 7.83.0 also clears sensitive headers on cross-port requests.

We are processing your report and will contact the guzzle team within 24 hours. 15 days ago
We have contacted a member of the guzzle team and are waiting to hear back 14 days ago
Graham Campbell
14 days ago

Maintainer


Interesting. We originally did not consider cross-port redirects a problem because curl did not filter them. The fact that curl has changed their position on this, maybe changes ours too. I'll have a chat with some people and get back to you. :)

Graham Campbell
12 days ago

Maintainer


FYI https://curl.se/docs/CVE-2022-27776.html

haxatron
12 days ago

Researcher


Yes thats the one i was talking about. It also includes the https downgrade problem guzzle recently fixed.

We have sent a follow up to the guzzle team. We will try again in 7 days. 11 days ago
Graham Campbell validated this vulnerability 11 days ago

We have discussed this internally, and we will proceed with treating a change in port as a change in origin, so we are treating this as a security vulnerability. Thanks for being so diligent in your reviews of our recent changes, @haxatron.

haxatron has been awarded the disclosure bounty
The fix bounty is now up for grabs
The researcher's credibility has increased: +7
Graham Campbell
11 days ago

Maintainer


As usual, I will provide another update within 10 business days. :)

We have sent a fix follow up to the guzzle team. We will try again in 7 days. 8 days ago
Graham Campbell
6 days ago

Maintainer


Please review the following advisory draft, @haxatron:

### Impact

`Authorization` and `Cookie` headers on requests are sensitive information. On making a request which responds with a redirect to a URI with a different port, if we choose to follow it, we should remove the `Authorization` and `Cookie` headers from the request, before containing. Previously, we would only consider a change in host or scheme.

### Patches

Affected Guzzle 7 users should upgrade to Guzzle 7.4.5 as soon as possible. Affected users using any earlier series of Guzzle should upgrade to Guzzle 6.5.8 or 7.4.5. Note that a partial fix was implemented in Guzzle 7.4.2, where a change in host would trigger removal of the curl-added Authorization header, however this earlier fix did not cover change in scheme or change in port.

### Workarounds

An alternative approach would be to use your own redirect middleware, rather than ours, if you are unable to upgrade. If you do not require or expect redirects to be followed, one should simply disable redirects all together.

### References

* [RFC9110 Section 15.4](https://www.rfc-editor.org/rfc/rfc9110.html#name-redirection-3xx)
* [CVE-2022-27776](https://curl.se/docs/CVE-2022-27776.html)

### For more information

If you have any questions or comments about this advisory, please get in touch with us in `#guzzle` on the [PHP HTTP Slack](https://php-http.slack.com/). Do not report additional security advisories in that public channel, however - please follow our [vulnerability reporting process](https://github.com/guzzle/guzzle/security/policy).
haxatron
6 days ago

Researcher


I think the partial fix about curl auth part is wrong, because this one applies to cookie and non-curl added authorization

haxatron
6 days ago

Researcher


Otherwise both advisories lgtm

Graham Campbell
6 days ago

Maintainer


Oops - copy/paste error. Thanks for noticing. :)

Graham Campbell confirmed that a fix has been merged on a52f04 5 days ago
Graham Campbell has been awarded the fix bounty
Graham Campbell
5 days ago

Maintainer


We have been allocated CVE-2022-31091.

to join this conversation