made HTTP headers coming from proxies non-trusted by default
This commit is contained in:
parent
cf1714c9db
commit
932cd10477
12
UPDATE.md
12
UPDATE.md
@ -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
|
API of the framework. If you "hack" the core, you should probably follow the
|
||||||
timeline closely anyway.
|
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
|
RC3 to RC4
|
||||||
----------
|
----------
|
||||||
|
|
||||||
* Annotation classes must be annotated with @Annotation
|
* Annotation classes must be annotated with @Annotation
|
||||||
(see the validator constraints for examples)
|
(see the validator constraints for examples)
|
||||||
|
|
||||||
|
@ -47,6 +47,7 @@ class Configuration implements ConfigurationInterface
|
|||||||
$rootNode
|
$rootNode
|
||||||
->children()
|
->children()
|
||||||
->scalarNode('charset')->end()
|
->scalarNode('charset')->end()
|
||||||
|
->scalarNode('proxy')->defaultFalse()->end()
|
||||||
->scalarNode('secret')->isRequired()->end()
|
->scalarNode('secret')->isRequired()->end()
|
||||||
->scalarNode('exception_controller')->defaultValue('Symfony\\Bundle\\FrameworkBundle\\Controller\\ExceptionController::showAction')->end()
|
->scalarNode('exception_controller')->defaultValue('Symfony\\Bundle\\FrameworkBundle\\Controller\\ExceptionController::showAction')->end()
|
||||||
->scalarNode('ide')->defaultNull()->end()
|
->scalarNode('ide')->defaultNull()->end()
|
||||||
|
@ -66,6 +66,8 @@ class FrameworkExtension extends Extension
|
|||||||
$container->setParameter('kernel.secret', $config['secret']);
|
$container->setParameter('kernel.secret', $config['secret']);
|
||||||
$container->setParameter('exception_listener.controller', $config['exception_controller']);
|
$container->setParameter('exception_listener.controller', $config['exception_controller']);
|
||||||
|
|
||||||
|
$container->setParameter('kernel.proxy', $config['proxy']);
|
||||||
|
|
||||||
if (!empty($config['test'])) {
|
if (!empty($config['test'])) {
|
||||||
$loader->load('test.xml');
|
$loader->load('test.xml');
|
||||||
}
|
}
|
||||||
|
@ -24,7 +24,7 @@ use Symfony\Bundle\FrameworkBundle\DependencyInjection\Compiler\CompilerDebugDum
|
|||||||
use Symfony\Component\DependencyInjection\ContainerBuilder;
|
use Symfony\Component\DependencyInjection\ContainerBuilder;
|
||||||
use Symfony\Component\DependencyInjection\Compiler\PassConfig;
|
use Symfony\Component\DependencyInjection\Compiler\PassConfig;
|
||||||
use Symfony\Component\DependencyInjection\Scope;
|
use Symfony\Component\DependencyInjection\Scope;
|
||||||
use Symfony\Component\HttpFoundation\File\File;
|
use Symfony\Component\HttpFoundation\Request;
|
||||||
use Symfony\Component\HttpKernel\Bundle\Bundle;
|
use Symfony\Component\HttpKernel\Bundle\Bundle;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -34,6 +34,13 @@ use Symfony\Component\HttpKernel\Bundle\Bundle;
|
|||||||
*/
|
*/
|
||||||
class FrameworkBundle extends Bundle
|
class FrameworkBundle extends Bundle
|
||||||
{
|
{
|
||||||
|
public function boot()
|
||||||
|
{
|
||||||
|
if ($this->container->getParameter('kernel.proxy')) {
|
||||||
|
Request::trustProxyData();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
public function build(ContainerBuilder $container)
|
public function build(ContainerBuilder $container)
|
||||||
{
|
{
|
||||||
parent::build($container);
|
parent::build($container);
|
||||||
|
@ -20,6 +20,8 @@ use Symfony\Component\HttpFoundation\SessionStorage\NativeSessionStorage;
|
|||||||
*/
|
*/
|
||||||
class Request
|
class Request
|
||||||
{
|
{
|
||||||
|
static protected $trustProxy = false;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @var \Symfony\Component\HttpFoundation\ParameterBag
|
* @var \Symfony\Component\HttpFoundation\ParameterBag
|
||||||
*/
|
*/
|
||||||
@ -322,6 +324,17 @@ class Request
|
|||||||
$_REQUEST = array_merge($_GET, $_POST);
|
$_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.
|
* Gets a "parameter" value.
|
||||||
*
|
*
|
||||||
@ -397,7 +410,7 @@ class Request
|
|||||||
if ($proxy) {
|
if ($proxy) {
|
||||||
if ($this->server->has('HTTP_CLIENT_IP')) {
|
if ($this->server->has('HTTP_CLIENT_IP')) {
|
||||||
return $this->server->get('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');
|
return $this->server->get('HTTP_X_FORWARDED_FOR');
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -600,9 +613,9 @@ class Request
|
|||||||
return (
|
return (
|
||||||
(strtolower($this->server->get('HTTPS')) == 'on' || $this->server->get('HTTPS') == 1)
|
(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()
|
public function getHost()
|
||||||
{
|
{
|
||||||
if ($host = $this->headers->get('X_FORWARDED_HOST')) {
|
if (self::$trustProxy && $host = $this->headers->get('X_FORWARDED_HOST')) {
|
||||||
$elements = explode(',', $host);
|
$elements = explode(',', $host);
|
||||||
|
|
||||||
$host = trim($elements[count($elements) - 1]);
|
$host = trim($elements[count($elements) - 1]);
|
||||||
|
@ -21,6 +21,11 @@ use Symfony\Component\HttpFoundation\Request;
|
|||||||
|
|
||||||
class RequestTest extends \PHPUnit_Framework_TestCase
|
class RequestTest extends \PHPUnit_Framework_TestCase
|
||||||
{
|
{
|
||||||
|
public function setUp()
|
||||||
|
{
|
||||||
|
Request::trustProxyData();
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @covers Symfony\Component\HttpFoundation\Request::__construct
|
* @covers Symfony\Component\HttpFoundation\Request::__construct
|
||||||
*/
|
*/
|
||||||
|
Reference in New Issue
Block a user