Merge branch '2.2' into 2.3
* 2.2: added trusted hosts check Conflicts: src/Symfony/Bundle/FrameworkBundle/DependencyInjection/FrameworkExtension.php
This commit is contained in:
commit
f8ffb80067
@ -68,6 +68,13 @@ class Configuration implements ConfigurationInterface
|
||||
->scalarNode('ide')->defaultNull()->end()
|
||||
->booleanNode('test')->end()
|
||||
->scalarNode('default_locale')->defaultValue('en')->end()
|
||||
->arrayNode('trusted_hosts')
|
||||
->beforeNormalization()
|
||||
->ifTrue(function($v) { return is_string($v); })
|
||||
->then(function($v) { return array($v); })
|
||||
->end()
|
||||
->prototype('scalar')->end()
|
||||
->end()
|
||||
->end()
|
||||
;
|
||||
|
||||
|
@ -69,7 +69,7 @@ class FrameworkExtension extends Extension
|
||||
}
|
||||
|
||||
$container->setParameter('kernel.http_method_override', $config['http_method_override']);
|
||||
|
||||
$container->setParameter('kernel.trusted_hosts', $config['trusted_hosts']);
|
||||
$container->setParameter('kernel.trusted_proxies', $config['trusted_proxies']);
|
||||
$container->setParameter('kernel.default_locale', $config['default_locale']);
|
||||
|
||||
|
@ -49,6 +49,10 @@ class FrameworkBundle extends Bundle
|
||||
if ($this->container->getParameter('kernel.http_method_override')) {
|
||||
Request::enableHttpMethodParameterOverride();
|
||||
}
|
||||
|
||||
if ($trustedHosts = $this->container->getParameter('kernel.trusted_hosts')) {
|
||||
Request::setTrustedHosts($trustedHosts);
|
||||
}
|
||||
}
|
||||
|
||||
public function build(ContainerBuilder $container)
|
||||
|
@ -22,7 +22,7 @@ class ConfigurationTest extends \PHPUnit_Framework_TestCase
|
||||
$config = $processor->processConfiguration(new Configuration(), array(array('secret' => 's3cr3t')));
|
||||
|
||||
$this->assertEquals(
|
||||
array_merge(array('secret' => 's3cr3t'), self::getBundleDefaultConfig()),
|
||||
array_merge(array('secret' => 's3cr3t', 'trusted_hosts' => array()), self::getBundleDefaultConfig()),
|
||||
$config
|
||||
);
|
||||
}
|
||||
|
@ -37,6 +37,16 @@ class Request
|
||||
|
||||
protected static $trustedProxies = array();
|
||||
|
||||
/**
|
||||
* @var string[]
|
||||
*/
|
||||
protected static $trustedHostPatterns = array();
|
||||
|
||||
/**
|
||||
* @var string[]
|
||||
*/
|
||||
protected static $trustedHosts = array();
|
||||
|
||||
/**
|
||||
* Names for headers that can be trusted when
|
||||
* using trusted proxies.
|
||||
@ -486,6 +496,32 @@ class Request
|
||||
return self::$trustedProxies;
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets a list of trusted host patterns.
|
||||
*
|
||||
* You should only list the hosts you manage using regexs.
|
||||
*
|
||||
* @param array $hostPatterns A list of trusted host patterns
|
||||
*/
|
||||
public static function setTrustedHosts(array $hostPatterns)
|
||||
{
|
||||
self::$trustedHostPatterns = array_map(function ($hostPattern) {
|
||||
return sprintf('{%s}i', str_replace('}', '\\}', $hostPattern));
|
||||
}, $hostPatterns);
|
||||
// we need to reset trusted hosts on trusted host patterns change
|
||||
self::$trustedHosts = array();
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the list of trusted host patterns.
|
||||
*
|
||||
* @return array An array of trusted host patterns.
|
||||
*/
|
||||
public static function getTrustedHosts()
|
||||
{
|
||||
return self::$trustedHostPatterns;
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets the name for trusted headers.
|
||||
*
|
||||
@ -1068,6 +1104,24 @@ class Request
|
||||
throw new \UnexpectedValueException('Invalid Host');
|
||||
}
|
||||
|
||||
if (count(self::$trustedHostPatterns) > 0) {
|
||||
// to avoid host header injection attacks, you should provide a list of trusted host patterns
|
||||
|
||||
if (in_array($host, self::$trustedHosts)) {
|
||||
return $host;
|
||||
}
|
||||
|
||||
foreach (self::$trustedHostPatterns as $pattern) {
|
||||
if (preg_match($pattern, $host)) {
|
||||
self::$trustedHosts[] = $host;
|
||||
|
||||
return $host;
|
||||
}
|
||||
}
|
||||
|
||||
throw new \UnexpectedValueException('Untrusted Host');
|
||||
}
|
||||
|
||||
return $host;
|
||||
}
|
||||
|
||||
|
@ -1501,6 +1501,37 @@ class RequestTest extends \PHPUnit_Framework_TestCase
|
||||
)
|
||||
);
|
||||
}
|
||||
|
||||
public function testTrustedHosts()
|
||||
{
|
||||
// create a request
|
||||
$request = Request::create('/');
|
||||
|
||||
// no trusted host set -> no host check
|
||||
$request->headers->set('host', 'evil.com');
|
||||
$this->assertEquals('evil.com', $request->getHost());
|
||||
|
||||
// add a trusted domain and all its subdomains
|
||||
Request::setTrustedHosts(array('.*\.?trusted.com$'));
|
||||
|
||||
// untrusted host
|
||||
$request->headers->set('host', 'evil.com');
|
||||
try {
|
||||
$request->getHost();
|
||||
$this->fail('Request::getHost() should throw an exception when host is not trusted.');
|
||||
} catch (\UnexpectedValueException $e) {
|
||||
$this->assertEquals('Untrusted Host', $e->getMessage());
|
||||
}
|
||||
|
||||
// trusted hosts
|
||||
$request->headers->set('host', 'trusted.com');
|
||||
$this->assertEquals('trusted.com', $request->getHost());
|
||||
$request->headers->set('host', 'subdomain.trusted.com');
|
||||
$this->assertEquals('subdomain.trusted.com', $request->getHost());
|
||||
|
||||
// reset request for following tests
|
||||
Request::setTrustedHosts(array());
|
||||
}
|
||||
}
|
||||
|
||||
class RequestContentProxy extends Request
|
||||
|
Reference in New Issue
Block a user