From e66a32b65a28f8e918d2dad8b961a1fb3ddeb39c Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jan=20Tu=C5=BEil?= Date: Mon, 4 Nov 2024 14:10:12 +0100 Subject: [PATCH] RequestFactory: extract port from x-forwarded-host (#230) --- src/Http/RequestFactory.php | 10 ++- .../RequestFactory.proxy.x-forwarded.phpt | 65 ++++++++++++++++++- 2 files changed, 71 insertions(+), 4 deletions(-) diff --git a/src/Http/RequestFactory.php b/src/Http/RequestFactory.php index 2a6b6788..f44490e7 100644 --- a/src/Http/RequestFactory.php +++ b/src/Http/RequestFactory.php @@ -347,8 +347,14 @@ private function useNonstandardProxy(Url $url): ?string if (isset($xForwardedForRealIpKey) && !empty($_SERVER['HTTP_X_FORWARDED_HOST'])) { $xForwardedHost = explode(',', $_SERVER['HTTP_X_FORWARDED_HOST']); - if (isset($xForwardedHost[$xForwardedForRealIpKey])) { - $url->setHost(trim($xForwardedHost[$xForwardedForRealIpKey])); + if ( + isset($xForwardedHost[$xForwardedForRealIpKey]) + && ($pair = $this->parseHostAndPort(trim($xForwardedHost[$xForwardedForRealIpKey]))) + ) { + $url->setHost($pair[0]); + if (isset($pair[1])) { + $url->setPort($pair[1]); + } } } diff --git a/tests/Http/RequestFactory.proxy.x-forwarded.phpt b/tests/Http/RequestFactory.proxy.x-forwarded.phpt index d44753cf..7b3fa87b 100644 --- a/tests/Http/RequestFactory.proxy.x-forwarded.phpt +++ b/tests/Http/RequestFactory.proxy.x-forwarded.phpt @@ -31,6 +31,43 @@ test('', function () { $url = $factory->fromGlobals()->getUrl(); Assert::same('otherhost', $url->getHost()); + Assert::same(80, $url->getPort()); +}); + +test('', function () { + $_SERVER = [ + 'REMOTE_ADDR' => '127.0.0.3', + 'REMOTE_HOST' => 'localhost', + 'HTTP_X_FORWARDED_FOR' => '23.75.45.200', + 'HTTP_X_FORWARDED_HOST' => 'otherhost:8080', + ]; + + $factory = new RequestFactory; + $factory->setProxy('127.0.0.3'); + Assert::same('23.75.45.200', $factory->fromGlobals()->getRemoteAddress()); + Assert::same('a23-75-45-200.deploy.static.akamaitechnologies.com', $factory->fromGlobals()->getRemoteHost()); + + $url = $factory->fromGlobals()->getUrl(); + Assert::same('otherhost', $url->getHost()); + Assert::same(8080, $url->getPort()); +}); + +test('', function () { + $_SERVER = [ + 'REMOTE_ADDR' => '127.0.0.3', + 'HTTP_X_FORWARDED_FOR' => '23.75.45.200', + 'HTTP_X_FORWARDED_HOST' => 'otherhost', + 'HTTP_X_FORWARDED_PROTO' => 'https', + 'HTTP_X_FORWARDED_PORT' => '8080', + ]; + + $factory = new RequestFactory; + $factory->setProxy('127.0.0.3'); + + $url = $factory->fromGlobals()->getUrl(); + Assert::same('https', $url->getScheme()); + Assert::same('otherhost', $url->getHost()); + Assert::same(8080, $url->getPort()); }); test('', function () { @@ -45,10 +82,34 @@ test('', function () { $factory->setProxy('10.0.0.0/24'); Assert::same('172.16.0.1', $factory->fromGlobals()->getRemoteAddress()); Assert::same('172.16.0.1', $factory->fromGlobals()->getRemoteHost()); - Assert::same('real', $factory->fromGlobals()->getUrl()->getHost()); + + $url = $factory->fromGlobals()->getUrl(); + Assert::same('real', $url->getHost()); + Assert::same(80, $url->getPort()); $factory->setProxy(['10.0.0.1', '10.0.0.2']); Assert::same('172.16.0.1', $factory->fromGlobals()->getRemoteAddress()); Assert::same('172.16.0.1', $factory->fromGlobals()->getRemoteHost()); - Assert::same('real', $factory->fromGlobals()->getUrl()->getHost()); + + $url = $factory->fromGlobals()->getUrl(); + Assert::same('real', $url->getHost()); + Assert::same(80, $url->getPort()); +}); + +test('', function () { + $_SERVER = [ + 'REMOTE_ADDR' => '10.0.0.2', //proxy2 + 'REMOTE_HOST' => 'proxy2', + 'HTTP_X_FORWARDED_FOR' => '123.123.123.123, not-ip.com, 172.16.0.1, 10.0.0.1', + 'HTTP_X_FORWARDED_HOST' => 'fake, not-ip.com, real:8080, proxy1', + ]; + + $factory = new RequestFactory; + $factory->setProxy(['10.0.0.1', '10.0.0.2']); + Assert::same('172.16.0.1', $factory->fromGlobals()->getRemoteAddress()); + Assert::same('172.16.0.1', $factory->fromGlobals()->getRemoteHost()); + + $url = $factory->fromGlobals()->getUrl(); + Assert::same('real', $url->getHost()); + Assert::same(8080, $url->getPort()); });