Merge pull request #41531 from nextcloud/backport/41526/stable23

[stable23] Reverse X-Forwarded-For list to read the correct proxy remote address
This commit is contained in:
Arthur Schiwon 2023-11-16 10:44:02 +01:00 committed by GitHub
commit cde8e938e9
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
2 changed files with 40 additions and 8 deletions

View file

@ -637,9 +637,11 @@ class Request implements \ArrayAccess, \Countable, IRequest {
// only have one default, so we cannot ship an insecure product out of the box
]);
foreach ($forwardedForHeaders as $header) {
// Read the x-forwarded-for headers and values in reverse order as per
// https://developer.mozilla.org/en-US/docs/Web/HTTP/Headers/X-Forwarded-For#selecting_an_ip_address
foreach (array_reverse($forwardedForHeaders) as $header) {
if (isset($this->server[$header])) {
foreach (explode(',', $this->server[$header]) as $IP) {
foreach (array_reverse(explode(',', $this->server[$header])) as $IP) {
$IP = trim($IP);
// remove brackets from IPv6 addresses
@ -647,6 +649,10 @@ class Request implements \ArrayAccess, \Countable, IRequest {
$IP = substr($IP, 1, -1);
}
if ($this->isTrustedProxy($trustedProxies, $IP)) {
continue;
}
if (filter_var($IP, FILTER_VALIDATE_IP) !== false) {
return $IP;
}

View file

@ -481,7 +481,33 @@ class RequestTest extends \Test\TestCase {
$this->stream
);
$this->assertSame('10.4.0.5', $request->getRemoteAddress());
$this->assertSame('10.4.0.4', $request->getRemoteAddress());
}
public function testGetRemoteAddressWithMultipleTrustedRemotes() {
$this->config
->expects($this->exactly(2))
->method('getSystemValue')
->willReturnMap([
['trusted_proxies', [], ['10.0.0.2', '::1']],
['forwarded_for_headers', ['HTTP_X_FORWARDED_FOR'], ['HTTP_X_FORWARDED']],
]);
$request = new Request(
[
'server' => [
'REMOTE_ADDR' => '10.0.0.2',
'HTTP_X_FORWARDED' => '10.4.0.5, 10.4.0.4, ::1',
'HTTP_X_FORWARDED_FOR' => '192.168.0.233'
],
],
$this->secureRandom,
$this->config,
$this->csrfTokenManager,
$this->stream
);
$this->assertSame('10.4.0.4', $request->getRemoteAddress());
}
public function testGetRemoteAddressIPv6WithSingleTrustedRemote() {
@ -510,7 +536,7 @@ class RequestTest extends \Test\TestCase {
$this->stream
);
$this->assertSame('10.4.0.5', $request->getRemoteAddress());
$this->assertSame('10.4.0.4', $request->getRemoteAddress());
}
public function testGetRemoteAddressVerifyPriorityHeader() {
@ -524,9 +550,9 @@ class RequestTest extends \Test\TestCase {
->method('getSystemValue')
->with('forwarded_for_headers')
->willReturn([
'HTTP_CLIENT_IP',
'HTTP_X_FORWARDED',
'HTTP_X_FORWARDED_FOR',
'HTTP_X_FORWARDED'
'HTTP_CLIENT_IP',
]);
$request = new Request(
@ -557,9 +583,9 @@ class RequestTest extends \Test\TestCase {
->method('getSystemValue')
->with('forwarded_for_headers')
->willReturn([
'HTTP_CLIENT_IP',
'HTTP_X_FORWARDED',
'HTTP_X_FORWARDED_FOR',
'HTTP_X_FORWARDED'
'HTTP_CLIENT_IP'
]);
$request = new Request(