Sensitive header uncleared on same-host, cross-port redirect in guzzle/guzzle
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.
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. :)
Yes thats the one i was talking about. It also includes the https downgrade problem guzzle recently fixed.
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.
As usual, I will provide another update within 10 business days. :)
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).
I think the partial fix about curl auth part is wrong, because this one applies to cookie and non-curl added authorization