Skip to content

Commit

Permalink
RequestFactory: fix X-Forwarded-Host mixup with remote host
Browse files Browse the repository at this point in the history
  • Loading branch information
JanTvrdik committed Mar 9, 2023
1 parent 09fc207 commit 2d11e41
Show file tree
Hide file tree
Showing 3 changed files with 20 additions and 22 deletions.
23 changes: 11 additions & 12 deletions src/Http/RequestFactory.php
Original file line number Diff line number Diff line change
Expand Up @@ -305,25 +305,24 @@ private function useForwardedProxy(Url $url, &$remoteAddr, &$remoteHost): void
$remoteAddr = str_contains($address, '[')
? substr($address, 1, strpos($address, ']') - 1) // IPv6
: explode(':', $address)[0]; // IPv4
$remoteHost = null;
}

if (isset($proxyParams['host']) && count($proxyParams['host']) === 1) {
$host = $proxyParams['host'][0];
$startingDelimiterPosition = strpos($host, '[');
if ($startingDelimiterPosition === false) { //IPv4
$remoteHostArr = explode(':', $host);
$remoteHost = $remoteHostArr[0];
$url->setHost($remoteHost);
if (isset($remoteHostArr[1])) {
$url->setPort((int) $remoteHostArr[1]);
$pair = explode(':', $host);
$url->setHost($pair[0]);
if (isset($pair[1])) {
$url->setPort((int) $pair[1]);
}
} else { //IPv6
$endingDelimiterPosition = strpos($host, ']');
$remoteHost = substr($host, strpos($host, '[') + 1, $endingDelimiterPosition - 1);
$url->setHost($remoteHost);
$remoteHostArr = explode(':', substr($host, $endingDelimiterPosition));
if (isset($remoteHostArr[1])) {
$url->setPort((int) $remoteHostArr[1]);
$url->setHost(substr($host, strpos($host, '[') + 1, $endingDelimiterPosition - 1));
$pair = explode(':', substr($host, $endingDelimiterPosition));
if (isset($pair[1])) {
$url->setPort((int) $pair[1]);
}
}
}
Expand Down Expand Up @@ -354,15 +353,15 @@ private function useNonstandardProxy(Url $url, &$remoteAddr, &$remoteHost): void
);
if ($xForwardedForWithoutProxies) {
$remoteAddr = trim(end($xForwardedForWithoutProxies));
$remoteHost = null;
$xForwardedForRealIpKey = key($xForwardedForWithoutProxies);
}
}

if (isset($xForwardedForRealIpKey) && !empty($_SERVER['HTTP_X_FORWARDED_HOST'])) {
$xForwardedHost = explode(',', $_SERVER['HTTP_X_FORWARDED_HOST']);
if (isset($xForwardedHost[$xForwardedForRealIpKey])) {
$remoteHost = trim($xForwardedHost[$xForwardedForRealIpKey]);
$url->setHost($remoteHost);
$url->setHost(trim($xForwardedHost[$xForwardedForRealIpKey]));
}
}
}
Expand Down
8 changes: 4 additions & 4 deletions tests/Http/RequestFactory.proxy.forwarded.phpt
Original file line number Diff line number Diff line change
Expand Up @@ -25,7 +25,7 @@ test('', function () {

$factory->setProxy('127.0.0.1/8');
Assert::same('23.75.45.200', $factory->fromGlobals()->getRemoteAddress());
Assert::same('192.168.0.1', @$factory->fromGlobals()->getRemoteHost()); // deprecated
Assert::null(@$factory->fromGlobals()->getRemoteHost()); // deprecated

$url = $factory->fromGlobals()->getUrl();
Assert::same('http', $url->getScheme());
Expand All @@ -43,7 +43,7 @@ test('', function () {

$factory->setProxy('127.0.0.3');
Assert::same('23.75.45.200', $factory->fromGlobals()->getRemoteAddress());
Assert::same('192.168.0.1', @$factory->fromGlobals()->getRemoteHost()); // deprecated
Assert::null(@$factory->fromGlobals()->getRemoteHost()); // deprecated

$url = $factory->fromGlobals()->getUrl();
Assert::same(8080, $url->getPort());
Expand All @@ -62,7 +62,7 @@ test('', function () {

$factory->setProxy('127.0.0.3');
Assert::same('2001:db8:cafe::17', $factory->fromGlobals()->getRemoteAddress());
Assert::same('2001:db8:cafe::18', @$factory->fromGlobals()->getRemoteHost()); // deprecated
Assert::null(@$factory->fromGlobals()->getRemoteHost()); // deprecated

$url = $factory->fromGlobals()->getUrl();
Assert::same('2001:db8:cafe::18', $url->getHost());
Expand All @@ -79,7 +79,7 @@ test('', function () {

$factory->setProxy('127.0.0.3');
Assert::same('2001:db8:cafe::17', $factory->fromGlobals()->getRemoteAddress());
Assert::same('2001:db8:cafe::18', @$factory->fromGlobals()->getRemoteHost()); // deprecated
Assert::null(@$factory->fromGlobals()->getRemoteHost()); // deprecated

$url = $factory->fromGlobals()->getUrl();
Assert::same(47832, $url->getPort());
Expand Down
11 changes: 5 additions & 6 deletions tests/Http/RequestFactory.proxy.x-forwarded.phpt
Original file line number Diff line number Diff line change
Expand Up @@ -27,7 +27,7 @@ test('', function () {

$factory->setProxy('127.0.0.1/8');
Assert::same('23.75.45.200', $factory->fromGlobals()->getRemoteAddress());
Assert::same('otherhost', @$factory->fromGlobals()->getRemoteHost()); // deprecated
Assert::null(@$factory->fromGlobals()->getRemoteHost()); // deprecated

$url = $factory->fromGlobals()->getUrl();
Assert::same('otherhost', $url->getHost());
Expand All @@ -44,12 +44,11 @@ test('', function () {
$factory = new RequestFactory;
$factory->setProxy('10.0.0.0/24');
Assert::same('172.16.0.1', $factory->fromGlobals()->getRemoteAddress());
Assert::same('real', @$factory->fromGlobals()->getRemoteHost()); // deprecated
Assert::null(@$factory->fromGlobals()->getRemoteHost()); // deprecated
Assert::same('real', $factory->fromGlobals()->getUrl()->getHost());

$factory->setProxy(['10.0.0.1', '10.0.0.2']);
Assert::same('172.16.0.1', $factory->fromGlobals()->getRemoteAddress());
Assert::same('real', @$factory->fromGlobals()->getRemoteHost()); // deprecated

$url = $factory->fromGlobals()->getUrl();
Assert::same('real', $url->getHost());
Assert::null(@$factory->fromGlobals()->getRemoteHost()); // deprecated
Assert::same('real', $factory->fromGlobals()->getUrl()->getHost());
});

0 comments on commit 2d11e41

Please sign in to comment.