Security
Headlines
HeadlinesLatestCVEs

Headline

CVE-2022-31091: Release 7.4.5 (#3043) · guzzle/guzzle@1dd98b0

Guzzle, an extensible PHP HTTP client. Authorization and Cookie headers on requests are sensitive information. In affected versions 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. 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. 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.

CVE
#php#auth#ssh

@@ -272,65 +272,105 @@ public function testInvokesOnRedirectForRedirects() self::assertTrue($call); }
public function crossOriginRedirectProvider() /** * @testWith [“digest”] * [“ntlm”] */ public function testRemoveCurlAuthorizationOptionsOnRedirectCrossHost($auth) { 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], ]; if (!defined(‘\CURLOPT_HTTPAUTH’)) { self::markTestSkipped(‘ext-curl is required for this test’); }
$mock = new MockHandler([ new Response(302, [‘Location’ => ‘http://test.com’]), static function (RequestInterface $request, $options) { self::assertFalse( isset($options[‘curl’][\CURLOPT_HTTPAUTH]), ‘curl options still contain CURLOPT_HTTPAUTH entry’ ); self::assertFalse( isset($options[‘curl’][\CURLOPT_USERPWD]), ‘curl options still contain CURLOPT_USERPWD entry’ ); return new Response(200); } ]); $handler = HandlerStack::create($mock); $client = new Client([‘handler’ => $handler]); $client->get('http://example.com?a=b’, [‘auth’ => ['testuser’, 'testpass’, $auth]]); }
/** * @dataProvider crossOriginRedirectProvider * @testWith [“digest”] * [“ntlm”] */ public function testHeadersTreatmentOnRedirect($originalUri, $targetUri, $shouldBePresent) public function testRemoveCurlAuthorizationOptionsOnRedirectCrossPort($auth) { $mock = new MockHandler([ new Response(302, [‘Location’ => $targetUri]), static function (RequestInterface $request) use ($shouldBePresent) { self::assertSame($shouldBePresent, $request->hasHeader(‘Authorization’)); self::assertSame($shouldBePresent, $request->hasHeader(‘Cookie’)); if (!defined(‘\CURLOPT_HTTPAUTH’)) { self::markTestSkipped(‘ext-curl is required for this test’); }
$mock = new MockHandler([ new Response(302, [‘Location’ => ‘http://example.com:81/’]), static function (RequestInterface $request, $options) { self::assertFalse( isset($options[‘curl’][\CURLOPT_HTTPAUTH]), ‘curl options still contain CURLOPT_HTTPAUTH entry’ ); self::assertFalse( isset($options[‘curl’][\CURLOPT_USERPWD]), ‘curl options still contain CURLOPT_USERPWD entry’ ); return new Response(200); } ]); $handler = HandlerStack::create($mock); $client = new Client([‘handler’ => $handler]); $client->get($originalUri, [‘auth’ => ['testuser’, ‘testpass’], ‘headers’ => [‘Cookie’ => ‘foo=bar’]]); $client->get('http://example.com?a=b’, [‘auth’ => ['testuser’, 'testpass’, $auth]]); }
public function testNotRemoveAuthorizationHeaderOnRedirect() /** * @testWith [“digest”] * [“ntlm”] */ public function testRemoveCurlAuthorizationOptionsOnRedirectCrossScheme($auth) { if (!defined(‘\CURLOPT_HTTPAUTH’)) { self::markTestSkipped(‘ext-curl is required for this test’); }
$mock = new MockHandler([ new Response(302, [‘Location’ => ‘http://example.com/2’]), static function (RequestInterface $request) { self::assertTrue($request->hasHeader(‘Authorization’)); new Response(302, [‘Location’ => ‘http://example.com?a=b’]), static function (RequestInterface $request, $options) { self::assertFalse( isset($options[‘curl’][\CURLOPT_HTTPAUTH]), ‘curl options still contain CURLOPT_HTTPAUTH entry’ ); self::assertFalse( isset($options[‘curl’][\CURLOPT_USERPWD]), ‘curl options still contain CURLOPT_USERPWD entry’ ); 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('https://example.com?a=b’, [‘auth’ => ['testuser’, 'testpass’, $auth]]); }
/** * @testWith [“digest”] * [“ntlm”] */ public function testRemoveCurlAuthorizationOptionsOnRedirect($auth) public function testRemoveCurlAuthorizationOptionsOnRedirectCrossSchemeSamePort($auth) { if (!defined(‘\CURLOPT_HTTPAUTH’)) { self::markTestSkipped(‘ext-curl is required for this test’); }
$mock = new MockHandler([ new Response(302, [‘Location’ => ‘http://test.com’]), new Response(302, [‘Location’ => ‘http://example.com:80?a=b’]), static function (RequestInterface $request, $options) { self::assertFalse( isset($options[‘curl’][\CURLOPT_HTTPAUTH]), @@ -345,7 +385,7 @@ static function (RequestInterface $request, $options) { ]); $handler = HandlerStack::create($mock); $client = new Client([‘handler’ => $handler]); $client->get('http://example.com?a=b’, [‘auth’ => ['testuser’, 'testpass’, $auth]]); $client->get('https://example.com?a=b’, [‘auth’ => ['testuser’, 'testpass’, $auth]]); }
/** @@ -377,6 +417,61 @@ static function (RequestInterface $request, $options) { $client->get('http://example.com?a=b’, [‘auth’ => ['testuser’, 'testpass’, $auth]]); }
public function crossOriginRedirectProvider() { return [ ['http://example.com/123’, 'http://example.com/’, false], ['http://example.com/123’, 'http://example.com:80/’, false], ['http://example.com:80/123’, 'http://example.com/’, false], ['http://example.com:80/123’, 'http://example.com:80/’, false], ['http://example.com/123’, 'https://example.com/’, true], ['http://example.com/123’, 'http://www.example.com/’, true], ['http://example.com/123’, 'http://example.com:81/’, true], ['http://example.com:80/123’, 'http://example.com:81/’, true], ['https://example.com/123’, 'https://example.com/’, false], ['https://example.com/123’, 'https://example.com:443/’, false], ['https://example.com:443/123’, 'https://example.com/’, false], ['https://example.com:443/123’, 'https://example.com:443/’, false], ['https://example.com/123’, 'http://example.com/’, true], ['https://example.com/123’, 'https://www.example.com/’, true], ['https://example.com/123’, 'https://example.com:444/’, true], ['https://example.com:443/123’, 'https://example.com:444/’, true], ]; }
/** * @dataProvider crossOriginRedirectProvider */ public function testHeadersTreatmentOnRedirect($originalUri, $targetUri, $isCrossOrigin) { $mock = new MockHandler([ new Response(302, [‘Location’ => $targetUri]), static function (RequestInterface $request) use ($isCrossOrigin) { self::assertSame(!$isCrossOrigin, $request->hasHeader(‘Authorization’)); self::assertSame(!$isCrossOrigin, $request->hasHeader(‘Cookie’));
return new Response(200); } ]); $handler = HandlerStack::create($mock); $client = new Client([‘handler’ => $handler]); $client->get($originalUri, [‘auth’ => ['testuser’, ‘testpass’], ‘headers’ => [‘Cookie’ => ‘foo=bar’]]); }
public function testNotRemoveAuthorizationHeaderOnRedirect() { $mock = new MockHandler([ new Response(302, [‘Location’ => ‘http://example.com/2’]), static function (RequestInterface $request) { self::assertTrue($request->hasHeader(‘Authorization’)); return new Response(200); } ]); $handler = HandlerStack::create($mock); $client = new Client([‘handler’ => $handler]); $client->get('http://example.com?a=b’, [‘auth’ => ['testuser’, ‘testpass’]]); }
/** * Verifies how RedirectMiddleware::modifyRequest() modifies the method and body of a request issued when * encountering a redirect response.

Related news

Gentoo Linux Security Advisory 202305-24

Gentoo Linux Security Advisory 202305-24 - Multiple vulnerabilities have been found in MediaWiki, the worst of which could result in denial of service. Versions greater than or equal to 1.25.2 are affected.

GHSA-q559-8m2m-g699: Change in port should be considered a change in origin

### 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 downgrade. Now, we consider any change in host, port or scheme to be a change in origin. ### 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. ### 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](http...

CVE: Latest News

CVE-2023-50976: Transactions API Authorization by oleiman · Pull Request #14969 · redpanda-data/redpanda
CVE-2023-6905
CVE-2023-6903
CVE-2023-6904
CVE-2023-3907