security #11828 n/a (nicolas-grekas, larowlan)
This PR was merged into the 2.3 branch. Discussion ---------- n/a n/a Commits -------1ee96a8
Test examples from Drupal SA-CORE-2014-0035506ee8
Fix potential DoS when parsing HOST
This commit is contained in:
commit
0aaabbfe8b
@ -1149,7 +1149,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)
|
// 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)
|
// 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.'"');
|
throw new \UnexpectedValueException('Invalid Host "'.$host.'"');
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1603,6 +1603,59 @@ class RequestTest extends \PHPUnit_Framework_TestCase
|
|||||||
// reset request for following tests
|
// reset request for following tests
|
||||||
Request::setTrustedHosts(array());
|
Request::setTrustedHosts(array());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @dataProvider getLongHostNames
|
||||||
|
*/
|
||||||
|
public function testVeryLongHosts($host)
|
||||||
|
{
|
||||||
|
$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, $expectedHost = null, $expectedPort = null)
|
||||||
|
{
|
||||||
|
$request = Request::create('/');
|
||||||
|
$request->headers->set('host', $host);
|
||||||
|
|
||||||
|
if ($isValid) {
|
||||||
|
$this->assertSame($expectedHost ?: $host, $request->getHost());
|
||||||
|
if ($expectedPort) {
|
||||||
|
$this->assertSame($expectedPort, $request->getPort());
|
||||||
|
}
|
||||||
|
} 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),
|
||||||
|
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)),
|
||||||
|
);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
class RequestContentProxy extends Request
|
class RequestContentProxy extends Request
|
||||||
|
Reference in New Issue
Block a user