[FrameworkBundle] allow configuring trusted proxies using semantic configuration
This commit is contained in:
parent
2c9e9cd0c2
commit
af9dd52752
@ -5,6 +5,7 @@ CHANGELOG
|
|||||||
-----
|
-----
|
||||||
|
|
||||||
* Added `framework.http_cache` configuration tree
|
* Added `framework.http_cache` configuration tree
|
||||||
|
* Added `framework.trusted_proxies` and `framework.trusted_headers` configuration options
|
||||||
|
|
||||||
5.1.0
|
5.1.0
|
||||||
-----
|
-----
|
||||||
|
@ -85,6 +85,20 @@ class Configuration implements ConfigurationInterface
|
|||||||
->beforeNormalization()->ifString()->then(function ($v) { return [$v]; })->end()
|
->beforeNormalization()->ifString()->then(function ($v) { return [$v]; })->end()
|
||||||
->prototype('scalar')->end()
|
->prototype('scalar')->end()
|
||||||
->end()
|
->end()
|
||||||
|
->scalarNode('trusted_proxies')->end()
|
||||||
|
->arrayNode('trusted_headers')
|
||||||
|
->fixXmlConfig('trusted_header')
|
||||||
|
->performNoDeepMerging()
|
||||||
|
->defaultValue(['x-forwarded-all', '!x-forwarded-host', '!x-forwarded-prefix'])
|
||||||
|
->beforeNormalization()->ifString()->then(function ($v) { return $v ? array_map('trim', explode(',', $v)) : []; })->end()
|
||||||
|
->enumPrototype()
|
||||||
|
->values([
|
||||||
|
'forwarded',
|
||||||
|
'x-forwarded-for', 'x-forwarded-host', 'x-forwarded-proto', 'x-forwarded-port',
|
||||||
|
'x-forwarded-all', '!x-forwarded-host', '!x-forwarded-prefix',
|
||||||
|
])
|
||||||
|
->end()
|
||||||
|
->end()
|
||||||
->scalarNode('error_controller')
|
->scalarNode('error_controller')
|
||||||
->defaultValue('error_controller')
|
->defaultValue('error_controller')
|
||||||
->end()
|
->end()
|
||||||
|
@ -65,6 +65,7 @@ use Symfony\Component\Form\FormTypeExtensionInterface;
|
|||||||
use Symfony\Component\Form\FormTypeGuesserInterface;
|
use Symfony\Component\Form\FormTypeGuesserInterface;
|
||||||
use Symfony\Component\Form\FormTypeInterface;
|
use Symfony\Component\Form\FormTypeInterface;
|
||||||
use Symfony\Component\HttpClient\ScopingHttpClient;
|
use Symfony\Component\HttpClient\ScopingHttpClient;
|
||||||
|
use Symfony\Component\HttpFoundation\Request;
|
||||||
use Symfony\Component\HttpKernel\CacheClearer\CacheClearerInterface;
|
use Symfony\Component\HttpKernel\CacheClearer\CacheClearerInterface;
|
||||||
use Symfony\Component\HttpKernel\CacheWarmer\CacheWarmerInterface;
|
use Symfony\Component\HttpKernel\CacheWarmer\CacheWarmerInterface;
|
||||||
use Symfony\Component\HttpKernel\Controller\ArgumentValueResolverInterface;
|
use Symfony\Component\HttpKernel\Controller\ArgumentValueResolverInterface;
|
||||||
@ -242,6 +243,11 @@ class FrameworkExtension extends Extension
|
|||||||
$container->setParameter('kernel.default_locale', $config['default_locale']);
|
$container->setParameter('kernel.default_locale', $config['default_locale']);
|
||||||
$container->setParameter('kernel.error_controller', $config['error_controller']);
|
$container->setParameter('kernel.error_controller', $config['error_controller']);
|
||||||
|
|
||||||
|
if (($config['trusted_proxies'] ?? false) && ($config['trusted_headers'] ?? false)) {
|
||||||
|
$container->setParameter('kernel.trusted_proxies', $config['trusted_proxies']);
|
||||||
|
$container->setParameter('kernel.trusted_headers', $this->resolveTrustedHeaders($config['trusted_headers']));
|
||||||
|
}
|
||||||
|
|
||||||
if (!$container->hasParameter('debug.file_link_format')) {
|
if (!$container->hasParameter('debug.file_link_format')) {
|
||||||
$links = [
|
$links = [
|
||||||
'textmate' => 'txmt://open?url=file://%%f&line=%%l',
|
'textmate' => 'txmt://open?url=file://%%f&line=%%l',
|
||||||
@ -2098,6 +2104,30 @@ class FrameworkExtension extends Extension
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private function resolveTrustedHeaders(array $headers): int
|
||||||
|
{
|
||||||
|
$trustedHeaders = 0;
|
||||||
|
|
||||||
|
foreach ($headers as $h) {
|
||||||
|
switch ($h) {
|
||||||
|
case 'forwarded': $trustedHeaders |= Request::HEADER_FORWARDED; break;
|
||||||
|
case 'x-forwarded-for': $trustedHeaders |= Request::HEADER_X_FORWARDED_FOR; break;
|
||||||
|
case 'x-forwarded-host': $trustedHeaders |= Request::HEADER_X_FORWARDED_HOST; break;
|
||||||
|
case 'x-forwarded-proto': $trustedHeaders |= Request::HEADER_X_FORWARDED_PROTO; break;
|
||||||
|
case 'x-forwarded-port': $trustedHeaders |= Request::HEADER_X_FORWARDED_PORT; break;
|
||||||
|
case '!x-forwarded-host': $trustedHeaders &= ~Request::HEADER_X_FORWARDED_HOST; break;
|
||||||
|
case 'x-forwarded-all':
|
||||||
|
if (!\in_array('!x-forwarded-prefix', $headers)) {
|
||||||
|
throw new LogicException('When using "x-forwarded-all" in "framework.trusted_headers", "!x-forwarded-prefix" must be explicitly listed until support for X-Forwarded-Prefix is implemented.');
|
||||||
|
}
|
||||||
|
$trustedHeaders |= Request::HEADER_X_FORWARDED_ALL;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return $trustedHeaders;
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* {@inheritdoc}
|
* {@inheritdoc}
|
||||||
*/
|
*/
|
||||||
|
@ -95,10 +95,6 @@ class FrameworkBundle extends Bundle
|
|||||||
if ($this->container->getParameter('kernel.http_method_override')) {
|
if ($this->container->getParameter('kernel.http_method_override')) {
|
||||||
Request::enableHttpMethodParameterOverride();
|
Request::enableHttpMethodParameterOverride();
|
||||||
}
|
}
|
||||||
|
|
||||||
if ($trustedHosts = $this->container->getParameter('kernel.trusted_hosts')) {
|
|
||||||
Request::setTrustedHosts($trustedHosts);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public function build(ContainerBuilder $container)
|
public function build(ContainerBuilder $container)
|
||||||
|
@ -42,6 +42,9 @@
|
|||||||
<xsd:attribute name="default-locale" type="xsd:string" />
|
<xsd:attribute name="default-locale" type="xsd:string" />
|
||||||
<xsd:attribute name="test" type="xsd:boolean" />
|
<xsd:attribute name="test" type="xsd:boolean" />
|
||||||
<xsd:attribute name="error-controller" type="xsd:string" />
|
<xsd:attribute name="error-controller" type="xsd:string" />
|
||||||
|
<xsd:attribute name="trusted_hosts" type="xsd:string" />
|
||||||
|
<xsd:attribute name="trusted_proxies" type="xsd:string" />
|
||||||
|
<xsd:attribute name="trusted_headers" type="xsd:string" />
|
||||||
</xsd:complexType>
|
</xsd:complexType>
|
||||||
|
|
||||||
<xsd:complexType name="form">
|
<xsd:complexType name="form">
|
||||||
|
@ -30,10 +30,7 @@ class ConfigurationTest extends TestCase
|
|||||||
$processor = new Processor();
|
$processor = new Processor();
|
||||||
$config = $processor->processConfiguration(new Configuration(true), [['secret' => 's3cr3t']]);
|
$config = $processor->processConfiguration(new Configuration(true), [['secret' => 's3cr3t']]);
|
||||||
|
|
||||||
$this->assertEquals(
|
$this->assertEquals(self::getBundleDefaultConfig(), $config);
|
||||||
array_merge(['secret' => 's3cr3t', 'trusted_hosts' => []], self::getBundleDefaultConfig()),
|
|
||||||
$config
|
|
||||||
);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public function getTestValidSessionName()
|
public function getTestValidSessionName()
|
||||||
@ -341,6 +338,13 @@ class ConfigurationTest extends TestCase
|
|||||||
'http_method_override' => true,
|
'http_method_override' => true,
|
||||||
'ide' => null,
|
'ide' => null,
|
||||||
'default_locale' => 'en',
|
'default_locale' => 'en',
|
||||||
|
'secret' => 's3cr3t',
|
||||||
|
'trusted_hosts' => [],
|
||||||
|
'trusted_headers' => [
|
||||||
|
'x-forwarded-all',
|
||||||
|
'!x-forwarded-host',
|
||||||
|
'!x-forwarded-prefix',
|
||||||
|
],
|
||||||
'csrf_protection' => [
|
'csrf_protection' => [
|
||||||
'enabled' => false,
|
'enabled' => false,
|
||||||
],
|
],
|
||||||
|
@ -5,6 +5,8 @@ CHANGELOG
|
|||||||
-----
|
-----
|
||||||
|
|
||||||
* made the public `http_cache` service handle requests when available
|
* made the public `http_cache` service handle requests when available
|
||||||
|
* allowed enabling trusted hosts and proxies using new `kernel.trusted_hosts`,
|
||||||
|
`kernel.trusted_proxies` and `kernel.trusted_headers` parameters
|
||||||
|
|
||||||
5.1.0
|
5.1.0
|
||||||
-----
|
-----
|
||||||
|
@ -764,7 +764,17 @@ abstract class Kernel implements KernelInterface, RebootableInterface, Terminabl
|
|||||||
$this->initializeBundles();
|
$this->initializeBundles();
|
||||||
$this->initializeContainer();
|
$this->initializeContainer();
|
||||||
|
|
||||||
return $this->container;
|
$container = $this->container;
|
||||||
|
|
||||||
|
if ($container->hasParameter('kernel.trusted_hosts') && $trustedHosts = $container->getParameter('kernel.trusted_hosts')) {
|
||||||
|
Request::setTrustedHosts($trustedHosts);
|
||||||
|
}
|
||||||
|
|
||||||
|
if ($container->hasParameter('kernel.trusted_proxies') && $container->hasParameter('kernel.trusted_headers') && $trustedProxies = $container->getParameter('kernel.trusted_proxies')) {
|
||||||
|
Request::setTrustedProxies(\is_array($trustedProxies) ? $trustedProxies : array_map('trim', explode(',', $trustedProxies)), $container->getParameter('kernel.trusted_headers'));
|
||||||
|
}
|
||||||
|
|
||||||
|
return $container;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
Reference in New Issue
Block a user