Fix potential DoS when parsing HOST
This commit is contained in:
parent
56a75179d1
commit
5506ee8f66
|
@ -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.'"');
|
||||
}
|
||||
|
||||
|
|
|
@ -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
|
||||
|
|
Reference in New Issue