made HTTP headers coming from proxies non-trusted by default

This commit is contained in:
Fabien Potencier 2011-07-05 19:38:29 +02:00
parent cf1714c9db
commit 932cd10477
6 changed files with 45 additions and 5 deletions

View File

@ -6,8 +6,20 @@ one. It only discusses changes that need to be done when using the "public"
API of the framework. If you "hack" the core, you should probably follow the
timeline closely anyway.
RC4 to RC5
----------
* To avoid security issues, HTTP headers coming from proxies are not trusted
anymore by default (like `HTTP_X_FORWARDED_FOR`, `X_FORWARDED_PROTO`, and
`X_FORWARDED_HOST`). If your application is behind a reverse proxy, add the
following configuration:
framework:
proxy: true
RC3 to RC4
----------
* Annotation classes must be annotated with @Annotation
(see the validator constraints for examples)

View File

@ -47,6 +47,7 @@ class Configuration implements ConfigurationInterface
$rootNode
->children()
->scalarNode('charset')->end()
->scalarNode('proxy')->defaultFalse()->end()
->scalarNode('secret')->isRequired()->end()
->scalarNode('exception_controller')->defaultValue('Symfony\\Bundle\\FrameworkBundle\\Controller\\ExceptionController::showAction')->end()
->scalarNode('ide')->defaultNull()->end()

View File

@ -66,6 +66,8 @@ class FrameworkExtension extends Extension
$container->setParameter('kernel.secret', $config['secret']);
$container->setParameter('exception_listener.controller', $config['exception_controller']);
$container->setParameter('kernel.proxy', $config['proxy']);
if (!empty($config['test'])) {
$loader->load('test.xml');
}

View File

@ -24,7 +24,7 @@ use Symfony\Bundle\FrameworkBundle\DependencyInjection\Compiler\CompilerDebugDum
use Symfony\Component\DependencyInjection\ContainerBuilder;
use Symfony\Component\DependencyInjection\Compiler\PassConfig;
use Symfony\Component\DependencyInjection\Scope;
use Symfony\Component\HttpFoundation\File\File;
use Symfony\Component\HttpFoundation\Request;
use Symfony\Component\HttpKernel\Bundle\Bundle;
/**
@ -34,6 +34,13 @@ use Symfony\Component\HttpKernel\Bundle\Bundle;
*/
class FrameworkBundle extends Bundle
{
public function boot()
{
if ($this->container->getParameter('kernel.proxy')) {
Request::trustProxyData();
}
}
public function build(ContainerBuilder $container)
{
parent::build($container);

View File

@ -20,6 +20,8 @@ use Symfony\Component\HttpFoundation\SessionStorage\NativeSessionStorage;
*/
class Request
{
static protected $trustProxy = false;
/**
* @var \Symfony\Component\HttpFoundation\ParameterBag
*/
@ -322,6 +324,17 @@ class Request
$_REQUEST = array_merge($_GET, $_POST);
}
/**
* Trusts $_SERVER entries coming from proxies.
*
* You should only call this method if your application
* is hosted behind a reverse proxy that you manage.
*/
static public function trustProxyData()
{
self::$trustProxy = true;
}
/**
* Gets a "parameter" value.
*
@ -397,7 +410,7 @@ class Request
if ($proxy) {
if ($this->server->has('HTTP_CLIENT_IP')) {
return $this->server->get('HTTP_CLIENT_IP');
} elseif ($this->server->has('HTTP_X_FORWARDED_FOR')) {
} elseif (self::$trustProxy && $this->server->has('HTTP_X_FORWARDED_FOR')) {
return $this->server->get('HTTP_X_FORWARDED_FOR');
}
}
@ -600,9 +613,9 @@ class Request
return (
(strtolower($this->server->get('HTTPS')) == 'on' || $this->server->get('HTTPS') == 1)
||
(strtolower($this->headers->get('SSL_HTTPS')) == 'on' || $this->headers->get('SSL_HTTPS') == 1)
(self::$trustProxy && strtolower($this->headers->get('SSL_HTTPS')) == 'on' || $this->headers->get('SSL_HTTPS') == 1)
||
(strtolower($this->headers->get('X_FORWARDED_PROTO')) == 'https')
(self::$trustProxy && strtolower($this->headers->get('X_FORWARDED_PROTO')) == 'https')
);
}
@ -613,7 +626,7 @@ class Request
*/
public function getHost()
{
if ($host = $this->headers->get('X_FORWARDED_HOST')) {
if (self::$trustProxy && $host = $this->headers->get('X_FORWARDED_HOST')) {
$elements = explode(',', $host);
$host = trim($elements[count($elements) - 1]);

View File

@ -21,6 +21,11 @@ use Symfony\Component\HttpFoundation\Request;
class RequestTest extends \PHPUnit_Framework_TestCase
{
public function setUp()
{
Request::trustProxyData();
}
/**
* @covers Symfony\Component\HttpFoundation\Request::__construct
*/