8000 Merge branch '2.3' · helmer/symfony@57531d4 · GitHub
[go: up one dir, main page]

8000 Skip to content

Commit 57531d4

Browse files
committed
Merge branch '2.3'
* 2.3: added trusted hosts check
2 parents 578f61a + f8ffb80 commit 57531d4

File tree

6 files changed

+98
-2
lines changed

6 files changed

+98
-2
lines changed

src/Symfony/Bundle/FrameworkBundle/DependencyInjection/Configuration.php

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -68,6 +68,13 @@ public function getConfigTreeBuilder()
6868
->scalarNode('ide')->defaultNull()->end()
6969
->booleanNode('test')->end()
7070
->scalarNode('default_locale')->defaultValue('en')->end()
71+
->arrayNode('trusted_hosts')
72+
->beforeNormalization()
73+
->ifTrue(function($v) { return is_string($v); })
74+
->then(function($v) { return array($v); })
75+
->end()
76+
->prototype('scalar')->end()
77+
->end()
7178
->end()
7279
;
7380

src/Symfony/Bundle/FrameworkBundle/DependencyInjection/FrameworkExtension.php

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -69,7 +69,7 @@ public function load(array $configs, ContainerBuilder $container)
6969
}
7070

7171
$container->setParameter('kernel.http_method_override', $config['http_method_override']);
72-
72+
$container->setParameter('kernel.trusted_hosts', $config['trusted_hosts']);
7373
$container->setParameter('kernel.trusted_proxies', $config['trusted_proxies']);
7474
$container->setParameter('kernel.default_locale', $config['default_locale']);
7575

src/Symfony/Bundle/FrameworkBundle/FrameworkBundle.php

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -49,6 +49,10 @@ public function boot()
4949
if ($this->container->getParameter('kernel.http_method_override')) {
5050
Request::enableHttpMethodParameterOverride();
5151
}
52+
53+
if ($trustedHosts = $this->container->getParameter('kernel.trusted_hosts')) {
54+
Request::setTrustedHosts($trustedHosts);
55+
}
5256
}
5357

5458
public function build(ContainerBuilder $container)

src/Symfony/Bundle/FrameworkBundle/Tests/DependencyInjection/ConfigurationTest.php

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -22,7 +22,7 @@ public function testDefaultConfig()
2222
$config = $processor->processConfiguration(new Configuration(), array(array('secret' => 's3cr3t')));
2323

2424
$this->assertEquals(
25-
array_merge(array('secret' => 's3cr3t'), self::getBundleDefaultConfig()),
25+
array_merge(array('secret' => 's3cr3t', 'trusted_hosts' => array()), self::getBundleDefaultConfig()),
2626
$config
2727
);
2828
}

src/Symfony/Component/HttpFoundation/Request.php

Lines changed: 54 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -37,6 +37,16 @@ class Request
3737

3838
protected static $trustedProxies = array();
3939 8000

40+
/**
41+
* @var string[]
42+
*/
43+
protected static $trustedHostPatterns = array();
44+
45+
/**
46+
* @var string[]
47+
*/
48+
protected static $trustedHosts = array();
49+
4050
/**
4151
* Names for headers that can be trusted when
4252
* using trusted proxies.
@@ -493,6 +503,32 @@ public static function getTrustedProxies()
493503
return self::$trustedProxies;
494504
}
495505

506+
/**
507+
* Sets a list of trusted host patterns.
508+
*
509+
* You should only list the hosts you manage using regexs.
510+
*
511+
* @param array $hostPatterns A list of trusted host patterns
512+
*/
513+
public static function setTrustedHosts(array $hostPatterns)
514+
{
515+
self::$trustedHostPatterns = array_map(function ($hostPattern) {
516+
return sprintf('{%s}i', str_replace('}', '\\}', $hostPattern));
517+
}, $hostPatterns);
518+
// we need to reset trusted hosts on trusted host patterns change
519+
self::$trustedHosts = array();
520+
}
521+
522+
/**
523+
* Gets the list of trusted host patterns.
524+
*
525+
* @return array An array of trusted host patterns.
526+
*/
527+
public static function getTrustedHosts()
528+
{
529+
return self::$trustedHostPatterns;
530+
}
531+
496532
/**
497533
* Sets the name for trusted headers.
498534
*
@@ -1075,6 +1111,24 @@ public function getHost()
10751111
throw new \UnexpectedValueException('Invalid Host');
10761112
}
10771113

1114+
if (count(self::$trustedHostPatterns) > 0) {
1115+
// to avoid host header injection attacks, you should provide a list of trusted host patterns
1116+
1117+
if (in_array($host, self::$trustedHosts)) {
1118+
return $host;
1119+
}
1120+
1121+
foreach (self::$trustedHostPatterns as $pattern) {
1122+
if (preg_match($pattern, $host)) {
1123+
self::$trustedHosts[] = $host;
1124+
1125+
return $host;
1126+
}
1127+
}
1128+
1129+
throw new \UnexpectedValueException('Untrusted Host');
1130+
}
1131+
10781132
return $host;
10791133
}
10801134

src/Symfony/Component/HttpFoundation/Tests/RequestTest.php

Lines changed: 31 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1517,6 +1517,37 @@ public function iisRequestUriProvider()
15171517
)
15181518
);
15191519
}
1520+
1521+
public function testTrustedHosts()
1522+
{
1523+
// create a request
1524+
$request = Request::create('/');
1525+
1526+
// no trusted host set -> no host check
1527+
$request->headers->set('host', 'evil.com');
1528+
$this->assertEquals('evil.com', $request->getHost());
1529+
1530+
// add a trusted domain and all its subdomains
1531+
Request::setTrustedHosts(array('.*\.?trusted.com$'));
1532+
1533+
// untrusted host
1534+
$request->headers->set('host', 'evil.com');
1535+
try {
1536+
$request->getHost();
1537+
$this->fail('Request::getHost() should throw an exception when host is not trusted.');
1538+
} catch (\UnexpectedValueException $e) {
1539+
$this->assertEquals('Untrusted Host', $e->getMessage());
1540+
}
1541+
1542+
// trusted hosts
1543+
$request->headers->set('host', 'trusted.com');
1544+
$this->assertEquals('trusted.com', $request->getHost());
1545+
$request->headers->set('host', 'subdomain.trusted.com');
1546+
$this->assertEquals('subdomain.trusted.com', $request->getHost());
1547+
1548+
// reset request for following tests
1549+
Request::setTrustedHosts(array());
1550+
}
15201551
}
15211552

15221553
class RequestContentProxy extends Request

0 commit comments

Comments
 (0)
0