Merge pull request #41529 from nextcloud/backport/41526/stable25

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

View file

@ -605,9 +605,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
@ -615,6 +617,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

@ -445,7 +445,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->requestId,
$this->config,
$this->csrfTokenManager,
$this->stream
);
$this->assertSame('10.4.0.4', $request->getRemoteAddress());
}
public function testGetRemoteAddressIPv6WithSingleTrustedRemote() {
@ -474,7 +500,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() {
@ -487,9 +513,9 @@ class RequestTest extends \Test\TestCase {
)-> willReturnOnConsecutiveCalls(
['10.0.0.2'],
[
'HTTP_CLIENT_IP',
'HTTP_X_FORWARDED_FOR',
'HTTP_X_FORWARDED',
'HTTP_X_FORWARDED_FOR',
'HTTP_CLIENT_IP',
],
);
@ -520,9 +546,9 @@ class RequestTest extends \Test\TestCase {
)-> willReturnOnConsecutiveCalls(
['2001:db8:85a3:8d3:1319:8a2e:370:7348'],
[
'HTTP_CLIENT_IP',
'HTTP_X_FORWARDED',
'HTTP_X_FORWARDED_FOR',
'HTTP_X_FORWARDED'
'HTTP_CLIENT_IP',
],
);