From 5506ee8f6601288a171f229bff88d38dcd6ebdf3 Mon Sep 17 00:00:00 2001 From: Nicolas Grekas Date: Mon, 11 Aug 2014 10:25:24 +0200 Subject: [PATCH 1/2] Fix potential DoS when parsing HOST --- .../Component/HttpFoundation/Request.php | 3 +- .../HttpFoundation/Tests/RequestTest.php | 39 +++++++++++++++++++ 2 files changed, 41 insertions(+), 1 deletion(-) diff --git a/src/Symfony/Component/HttpFoundation/Request.php b/src/Symfony/Component/HttpFoundation/Request.php index d7053339bd..93767f4aad 100644 --- a/src/Symfony/Component/HttpFoundation/Request.php +++ b/src/Symfony/Component/HttpFoundation/Request.php @@ -1147,7 +1147,8 @@ class Request // as the host can come from the user (HTTP_HOST and depending on the configuration, SERVER_NAME too can come from the user) // check that it does not contain forbidden characters (see RFC 952 and RFC 2181) - if ($host && !preg_match('/^\[?(?:[a-zA-Z0-9-:\]_]+\.?)+$/', $host)) { + // use preg_replace() instead of preg_match() to prevent DoS attacks with long host names + if ($host && '' !== preg_replace('/(?:^\[)?[a-zA-Z0-9-:\]_]+\.?/', '', $host)) { throw new \UnexpectedValueException('Invalid Host "'.$host.'"'); } diff --git a/src/Symfony/Component/HttpFoundation/Tests/RequestTest.php b/src/Symfony/Component/HttpFoundation/Tests/RequestTest.php index 688f3094b9..e0cc1dcfd0 100644 --- a/src/Symfony/Component/HttpFoundation/Tests/RequestTest.php +++ b/src/Symfony/Component/HttpFoundation/Tests/RequestTest.php @@ -1594,6 +1594,45 @@ class RequestTest extends \PHPUnit_Framework_TestCase // reset request for following tests Request::setTrustedHosts(array()); } + + public function testVeryLongHost() + { + $host = 'a'.str_repeat('.a', 40000); + $start = microtime(true); + + $request = Request::create('/'); + $request->headers->set('host', $host); + $this->assertEquals($host, $request->getHost()); + $this->assertLessThan(1, microtime(true) - $start); + } + + /** + * @dataProvider getHostValidities + */ + public function testHostValidity($host, $isValid) + { + $request = Request::create('/'); + $request->headers->set('host', $host); + + if ($isValid) { + $this->assertSame($host, $request->getHost()); + } + } else { + $this->setExpectedException('UnexpectedValueException', 'Invalid Host'); + $request->getHost(); + } + } + + public function getHostValidities() + { + return array( + array('.a', false), + array('a..', false), + array('a.', true), + array("\xE9", false), + array('[::1]', true), + ); + } } class RequestContentProxy extends Request From 1ee96a8b1b0987ffe2a62dca7ad268bf9edfa9b8 Mon Sep 17 00:00:00 2001 From: Lee Rowlands Date: Fri, 22 Aug 2014 11:11:38 +1000 Subject: [PATCH 2/2] Test examples from Drupal SA-CORE-2014-003 --- .../HttpFoundation/Tests/RequestTest.php | 22 +++++++++++++++---- 1 file changed, 18 insertions(+), 4 deletions(-) diff --git a/src/Symfony/Component/HttpFoundation/Tests/RequestTest.php b/src/Symfony/Component/HttpFoundation/Tests/RequestTest.php index e0cc1dcfd0..88e0afbc8f 100644 --- a/src/Symfony/Component/HttpFoundation/Tests/RequestTest.php +++ b/src/Symfony/Component/HttpFoundation/Tests/RequestTest.php @@ -1595,9 +1595,11 @@ class RequestTest extends \PHPUnit_Framework_TestCase Request::setTrustedHosts(array()); } - public function testVeryLongHost() + /** + * @dataProvider getLongHostNames + */ + public function testVeryLongHosts($host) { - $host = 'a'.str_repeat('.a', 40000); $start = microtime(true); $request = Request::create('/'); @@ -1609,13 +1611,15 @@ class RequestTest extends \PHPUnit_Framework_TestCase /** * @dataProvider getHostValidities */ - public function testHostValidity($host, $isValid) + public function testHostValidity($host, $isValid, $expectedHost = null, $expectedPort = null) { $request = Request::create('/'); $request->headers->set('host', $host); if ($isValid) { - $this->assertSame($host, $request->getHost()); + $this->assertSame($expectedHost ?: $host, $request->getHost()); + if ($expectedPort) { + $this->assertSame($expectedPort, $request->getPort()); } } else { $this->setExpectedException('UnexpectedValueException', 'Invalid Host'); @@ -1631,6 +1635,16 @@ class RequestTest extends \PHPUnit_Framework_TestCase array('a.', true), array("\xE9", false), array('[::1]', true), + array('[::1]:80', true, '[::1]', 80), + array(str_repeat('.', 101), false), + ); + } + + public function getLongHostNames() + { + return array( + array('a'.str_repeat('.a', 40000)), + array(str_repeat(':', 101)), ); } }