10000 [FrameworkBundle][HttpKernel] Add support for `SYMFONY_TRUSTED_PROXIE… · symfony/symfony@60bd068 · GitHub
[go: up one dir, main page]

Skip to content

Commit 60bd068

Browse files
[FrameworkBundle][HttpKernel] Add support for SYMFONY_TRUSTED_PROXIES, SYMFONY_TRUSTED_HEADERS, SYMFONY_TRUST_X_SENDFILE_TYPE_HEADER and SYMFONY_TRUSTED_HOSTS env vars
1 parent 2ffd266 commit 60bd068

File tree

7 files changed

+57
-42
lines changed

7 files changed

+57
-42
lines changed

src/Symfony/Bundle/FrameworkBundle/CHANGELOG.md

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -16,6 +16,7 @@ CHANGELOG
1616
* Deprecate `session.sid_length` and `session.sid_bits_per_character` config options
1717
* Add the ability to use an existing service as a lock/semaphore resource
1818
* Add support for configuring multiple serializer instances via the configuration
19+
* Add support for `SYMFONY_TRUSTED_PROXIES`, `SYMFONY_TRUSTED_HEADERS`, `SYMFONY_TRUST_X_SENDFILE_TYPE_HEADER` and `SYMFONY_TRUSTED_HOSTS` env vars
1920

2021
7.1
2122
---

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

Lines changed: 7 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -90,7 +90,7 @@ public function getConfigTreeBuilder(): TreeBuilder
9090
->end()
9191
->scalarNode('trust_x_sendfile_type_header')
9292
->info('Set true to enable support for xsendfile in binary file responses.')
93-
->defaultFalse()
93+
->defaultValue('%env(bool:default::SYMFONY_TRUST_X_SENDFILE_TYPE_HEADER)%')
9494
->end()
9595
->scalarNode('ide')->defaultValue($this->debug ? '%env(default::SYMFONY_IDE)%' : null)->end()
9696
->booleanNode('test')->end()
@@ -108,26 +108,23 @@ public function getConfigTreeBuilder(): TreeBuilder
108108
->prototype('scalar')->end()
109109
->end()
110110
->arrayNode('trusted_hosts')
111-
->beforeNormalization()->ifString()->then(fn ($v) => [$v])->end()
111+
->beforeNormalization()->ifString()->then(static fn ($v) => $v ? [$v] : [])->end()
112112
->prototype('scalar')->end()
113+
->defaultValue(['%env(default::SYMFONY_TRUSTED_HOSTS)%'])
113114
->end()
114115
->variableNode('trusted_proxies')
115116
->beforeNormalization()
116117
->ifTrue(fn ($v) => 'private_ranges' === $v || 'PRIVATE_SUBNETS' === $v)
117118
->then(fn () => IpUtils::PRIVATE_SUBNETS)
118119
->end()
120+
->defaultValue(['%env(default::SYMFONY_TRUSTED_PROXIES)%'])
119121
->end()
120122
->arrayNode('trusted_headers')
121123
->fixXmlConfig('trusted_header')
122124
->performNoDeepMerging()
123-
->defaultValue(['x-forwarded-for', 'x-forwarded-port', 'x-forwarded-proto'])
124-
->beforeNormalization()->ifString()->then(fn ($v) => $v ? array_map('trim', explode(',', $v)) : [])->end()
125-
->enumPrototype()
126-
->values([
127-
'forwarded',
128-
'x-forwarded-for', 'x-forwarded-host', 'x-forwarded-proto', 'x-forwarded-port', 'x-forwarded-prefix',
129-
])
130-
->end()
125+
->beforeNormalization()->ifString()->then(static fn ($v) => $v ? [$v] : [])->end()
126+
->prototype('scalar')->end()
127+
->defaultValue(['%env(default::SYMFONY_TRUSTED_HEADERS)%'])
131128
->end()
132129
->scalarNode('error_controller')
133130
->defaultValue('error_controller')

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

Lines changed: 3 additions & 22 deletions
Original file line numberDiff line numberDiff line change
@@ -313,14 +313,14 @@ public function load(array $configs, ContainerBuilder $container): void
313313

314314
$container->setParameter('kernel.http_method_override', $config['http_method_override']);
315315
$container->setParameter('kernel.trust_x_sendfile_type_header', $config['trust_x_sendfile_type_header']);
316-
$container->setParameter('kernel.trusted_hosts', $config['trusted_hosts']);
316+
$container->setParameter('kernel.trusted_hosts', [0] === array_keys($config['trusted_hosts']) ? $config['trusted_hosts'][0] : $config['trusted_hosts']);
317317
$container->setParameter('kernel.default_locale', $config['default_locale']);
318318
$container->setParameter('kernel.enabled_locales', $config['enabled_locales']);
319319
$container->setParameter('kernel.error_controller', $config['error_controller']);
320320

321321
if (($config['trusted_proxies'] ?? false) && ($config['trusted_headers'] ?? false)) {
322-
$container->setParameter('kernel.trusted_proxies', $config['trusted_proxies']);
323-
$container->setParameter('kernel.trusted_headers', $this->resolveTrustedHeaders($config['trusted_headers']));
322+
$container->setParameter('kernel.trusted_proxies', \is_array($config['trusted_proxies']) && [0] === array_keys($config['trusted_proxies']) ? $config['trusted_proxies'][0] : $config['trusted_proxies']);
323+
$container->setParameter('kernel.trusted_headers', [0] === array_keys($config['trusted_headers']) ? $config['trusted_headers'][0] : $config['trusted_headers']);
324324
}
325325

326326
if (!$container->hasParameter('debug.file_link_format')) {
@@ -3114,25 +3114,6 @@ private function registerHtmlSanitizerConfiguration(array $config, ContainerBuil
31143114
}
31153115
}
31163116

3117-
private function resolveTrustedHeaders(array $headers): int
3118-
{
3119-
$trustedHeaders = 0;
3120-
3121-
foreach ($headers as $h) {
3122-
$trustedHeaders |= match ($h) {
3123-
'forwarded' => Request::HEADER_FORWARDED,
3124-
'x-forwarded-for' => Request::HEADER_X_FORWARDED_FOR,
3125-
'x-forwarded-host' => Request::HEADER_X_FORWARDED_HOST,
3126-
'x-forwarded-proto' => Request::HEADER_X_FORWARDED_PROTO,
3127-
'x-forwarded-port' => Request::HEADER_X_FORWARDED_PORT,
3128-
'x-forwarded-prefix' => Request::HEADER_X_FORWARDED_PREFIX,
3129-
default => 0,
3130-
};
3131-
}
3132-
3133-
return $trustedHeaders;
3134-
}
3135-
31363117
public function getXsdValidationBasePath(): string|false
31373118
{
31383119
return \dirname(__DIR__).'/Resources/config/schema';

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

Lines changed: 4 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -704,19 +704,16 @@ protected static function getBundleDefaultConfig()
704704
return [
705705
'http_method_override' => false,
706706
'handle_all_throwables' => true,
707-
'trust_x_sendfile_type_header' => false,
707+
'trust_x_sendfile_type_header' => '%env(bool:default::SYMFONY_TRUST_X_SENDFILE_TYPE_HEADER)%',
708708
'ide' => '%env(default::SYMFONY_IDE)%',
709709
'default_locale' => 'en',
710710
'enabled_locales' => [],
711711
'set_locale_from_accept_language' => false,
712712
'set_content_language_from_locale' => false,
713713
'secret' => 's3cr3t',
714-
'trusted_hosts' => [],
715-
'trusted_headers' => [
716-
'x-forwarded-for',
717-
'x-forwarded-port',
718-
'x-forwarded-proto',
719-
],
714+
'trusted_hosts' => ['%env(default::SYMFONY_TRUSTED_HOSTS)%'],
715+
'trusted_proxies' => ['%env(default::SYMFONY_TRUSTED_PROXIES)%'],
716+
'trusted_headers' => ['%env(default::SYMFONY_TRUSTED_HEADERS)%'],
720717
'csrf_protection' => [
721718
'enabled' => false,
722719
],

src/Symfony/Component/HttpKernel/CHANGELOG.md

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,7 @@ CHANGELOG
66

77
* Remove `@internal` flag and add `@final` to `ServicesResetter`
88
* Add support for `SYMFONY_DISABLE_RESOURCE_TRACKING` env var
9+
* Add support for configuring trusted proxies/headers/hosts via env vars
910

1011
7.1
1112
---

src/Symfony/Component/HttpKernel/Kernel.php

Lines changed: 22 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -393,7 +393,7 @@ protected function initializeContainer(): void
393393
$class = $this->getContainerClass();
394394
$buildDir = $this->warmupDir ?: $this->getBuildDir();
395395
$skip = $_SERVER['SYMFONY_DISABLE_RESOURCE_TRACKING'] ?? '';
396-
$skip = filter_var($skip, \FILTER_VALIDATE_BOOLEAN, \FILTER_NULL_ON_FAILURE) ?? explode(',', $skip);
396+
$skip = filter_var($skip, \FILTER_VALIDATE_BOOLEAN, \FILTER_NULL_ON_FAILURE) ?? explode(',', $skip);
397397
$cache = new ConfigCache($buildDir.'/'.$class.'.php', $this->debug, null, \is_array($skip) && ['*'] !== $skip ? $skip : ($skip ? [] : null));
398398

399399
$cachePath = $cache->getPath();
@@ -745,11 +745,30 @@ private function preBoot(): ContainerInterface
745745
$container = $this->container;
746746

747747
if ($container->hasParameter('kernel.trusted_hosts') && $trustedHosts = $container->getParameter('kernel.trusted_hosts')) {
748-
Request::setTrustedHosts($trustedHosts);
748+
Request::setTrustedHosts(\is_array($trustedHosts) ? $trustedHosts : preg_split('/\s*+,\s*+(?![^{]*})/', $trustedHosts));
749749
}
750750

751751
if ($container->hasParameter('kernel.trusted_proxies') && $container->hasParameter('kernel.trusted_headers') && $trustedProxies = $container->getParameter('kernel.trusted_proxies')) {
752-
Request::setTrustedProxies(\is_array($trustedProxies) ? $trustedProxies : array_map('trim', explode(',', $trustedProxies)), $container->getParameter('kernel.trusted_headers'));
752+
$trustedHeaders = $container->getParameter('kernel.trusted_headers');
753+
754+
if (\is_string($trustedHeaders)) {
755+
$trustedHeaders = array_map('trim', explode(',', $trustedHeaders));
756+
}
757+
758+
if (\is_array($trustedHeaders)) {
759+
$trustedHeaderSet = 0;
760+
761+
foreach ($trustedHeaders as $header) {
762+
if (!\defined($const = Request::class.'::HEADER_'.strtr(strtoupper($header), '-', '_'))) {
763+
throw new \InvalidArgumentException(\sprintf('The trusted header "%s" is not supported.', $header));
764+
}
765+
$trustedHeaderSet |= \constant($const);
766+
}
767+
} else {
768+
$trustedHeaderSet = $trustedHeaders ?? (Request::HEADER_X_FORWARDED_FOR | Request::HEADER_X_FORWARDED_PORT | Request::HEADER_X_FORWARDED_PROTO);
769+
}
770+
771+
Request::setTrustedProxies(\is_array($trustedProxies) ? $trustedProxies : array_map('trim', explode(',', $trustedProxies)), $trustedHeaderSet);
753772
}
754773

755774
return $container;

src/Symfony/Component/HttpKernel/Tests/KernelTest.php

Lines changed: 19 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -523,6 +523,25 @@ public function getContainerClass(): string
523523
$this->assertMatchesRegularExpression('/^[a-zA-Z_\x80-\xff][a-zA-Z0-9_\x80-\xff]*TestDebugContainer$/', $kernel->getContainerClass());
524524
}
525525

526+
public function testTrustedParameters()
527+
{
528+
$kernel = new CustomProjectDirKernel(function (ContainerBuilder $container) {
529+
$container->setParameter('kernel.trusted_hosts', '^a{2,3}.com$, ^b{2,}.com$');
530+
$container->setParameter('kernel.trusted_proxies', 'a,b');
531+
$container->setParameter('kernel.trusted_headers', 'x-forwarded-for');
532+
});
533+
$kernel->boot();
534+
535+
try {
536+
$this->assertSame(['{^a{2,3}.com$}i', '{^b{2,}.com$}i'], Request::getTrustedHosts());
537+
$this->assertSame(['a', 'b'], Request::getTrustedProxies());
538+
$this->assertSame(Request::HEADER_X_FORWARDED_FOR, Request::getTrustedHeaderSet());
539+
} finally {
540+
Request::setTrustedHosts([]);
541+
Request::setTrustedProxies([], 0);
542+
}
543+
}
544+
526545
/**
527546
* Returns a mock for the BundleInterface.
528547
*/

0 commit comments

Comments
 (0)
0