Skip to content

Commit 09ab76b

Browse files
committed
feature #13964 Allow to configure trusted proxies and headers using config options (javiereguiluz)
This PR was squashed before being merged into the 5.2 branch. Discussion ---------- Allow to configure trusted proxies and headers using config options Fixes #13890. If you agree with this, I'll add the XML and PHP config formats to the example. Commits ------- f06a712 Allow to configure trusted proxies and headers using config options
2 parents 6341ef2 + f06a712 commit 09ab76b

File tree

2 files changed

+113
-36
lines changed

2 files changed

+113
-36
lines changed

deployment/proxies.rst

Lines changed: 91 additions & 35 deletions
Original file line numberDiff line numberDiff line change
@@ -22,28 +22,69 @@ Solution: ``setTrustedProxies()``
2222
---------------------------------
2323

2424
To fix this, you need to tell Symfony which reverse proxy IP addresses to trust
25-
and what headers your reverse proxy uses to send information::
26-
27-
// public/index.php
28-
29-
// ...
30-
$request = Request::createFromGlobals();
31-
32-
// tell Symfony about your reverse proxy
33-
Request::setTrustedProxies(
34-
// the IP address (or range) of your proxy
35-
['192.0.0.1', '10.0.0.0/8'],
36-
37-
// trust *all* "X-Forwarded-*" headers
38-
Request::HEADER_X_FORWARDED_FOR | Request::HEADER_X_FORWARDED_HOST | Request::HEADER_X_FORWARDED_PORT | Request::HEADER_X_FORWARDED_PROTO
39-
40-
// or, if your proxy instead uses the "Forwarded" header
41-
// Request::HEADER_FORWARDED
42-
43-
// or, if you're using a well-known proxy
44-
// Request::HEADER_X_FORWARDED_AWS_ELB
45-
// Request::HEADER_X_FORWARDED_TRAEFIK
46-
);
25+
and what headers your reverse proxy uses to send information:
26+
27+
.. configuration-block::
28+
29+
.. config-block:: yaml
30+
31+
# config/packages/framework.yaml
32+
framework:
33+
# ...
34+
// the IP address (or range) of your proxy
35+
trusted_proxies: '192.0.0.1,10.0.0.0/8'
36+
// trust *all* "X-Forwarded-*" headers (the ! prefix means to not trust those headers)
37+
trusted_headers: ['x-forwarded-all', '!x-forwarded-host', '!x-forwarded-prefix']
38+
// or, if your proxy instead uses the "Forwarded" header
39+
trusted_headers: ['forwarded', '!x-forwarded-host', '!x-forwarded-prefix']
40+
// or, if you're using a wellknown proxy
41+
trusted_headers: [!php/const Symfony\\Component\\HttpFoundation\\Request::HEADER_X_FORWARDED_AWS_ELB, '!x-forwarded-host', '!x-forwarded-prefix']
42+
trusted_headers: [!php/const Symfony\\Component\\HttpFoundation\\Request::HEADER_X_FORWARDED_TRAEFIK, '!x-forwarded-host', '!x-forwarded-prefix']
43+
44+
.. config-block:: xml
45+
46+
<!-- config/packages/framework.xml -->
47+
<?xml version="1.0" encoding="UTF-8" ?>
48+
<container xmlns="http://symfony.com/schema/dic/services"
49+
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
50+
xmlns:framework="http://symfony.com/schema/dic/symfony"
51+
xsi:schemaLocation="http://symfony.com/schema/dic/services
52+
https://symfony.com/schema/dic/services/services-1.0.xsd
53+
http://symfony.com/schema/dic/symfony
54+
https://symfony.com/schema/dic/symfony/symfony-1.0.xsd">
55+
56+
<framework:config>
57+
<!-- the IP address (or range) of your proxy -->
58+
<framework:trusted-proxies>192.0.0.1,10.0.0.0/8</framework:trusted-proxies>
59+
60+
<!-- trust *all* "X-Forwarded-*" headers (the ! prefix means to not trust those headers) -->
61+
<framework:trusted-header>x-forwarded-all</framework:trusted-header>
62+
<framework:trusted-header>!x-forwarded-host</framework:trusted-header>
63+
<framework:trusted-header>!x-forwarded-prefix</framework:trusted-header>
64+
65+
<!-- or, if your proxy instead uses the "Forwarded" header -->
66+
<framework:trusted-header>forwarded</framework:trusted-header>
67+
<framework:trusted-header>!x-forwarded-host</framework:trusted-header>
68+
<framework:trusted-header>!x-forwarded-prefix</framework:trusted-header>
69+
</framework:config>
70+
</container>
71+
72+
.. config-block:: php
73+
74+
// config/packages/framework.php
75+
use Symfony\Component\HttpFoundation\Request;
76+
77+
$container->loadFromExtension('framework', [
78+
// the IP address (or range) of your proxy
79+
'trusted_proxies' => '192.0.0.1,10.0.0.0/8',
80+
// trust *all* "X-Forwarded-*" headers (the ! prefix means to not trust those headers)
81+
'trusted_headers' => ['x-forwarded-all', '!x-forwarded-host', '!x-forwarded-prefix'],
82+
// or, if your proxy instead uses the "Forwarded" header
83+
'trusted_headers' => ['forwarded', '!x-forwarded-host', '!x-forwarded-prefix'],
84+
// or, if you're using a wellknown proxy
85+
'trusted_headers' => [Request::HEADER_X_FORWARDED_AWS_ELB, '!x-forwarded-host', '!x-forwarded-prefix'],
86+
'trusted_headers' => [Request::HEADER_X_FORWARDED_TRAEFIK, '!x-forwarded-host', '!x-forwarded-prefix'],
87+
]);
4788
4889
.. deprecated:: 5.2
4990

@@ -61,6 +102,13 @@ The Request object has several ``Request::HEADER_*`` constants that control exac
61102
*which* headers from your reverse proxy are trusted. The argument is a bit field,
62103
so you can also pass your own value (e.g. ``0b00110``).
63104

105+
.. versionadded:: 5.2
106+
107+
The feature to configure trusted proxies and headers with ``trusted_proxies``
108+
and ``trusted_headers`` options was introduced in Symfony 5.2. In earlier
109+
Symfony versions you needed to use the ``Request::setTrustedProxies()``
110+
method in the ``public/index.php`` file.
111+
64112
But what if the IP of my Reverse Proxy Changes Constantly!
65113
----------------------------------------------------------
66114

@@ -74,17 +122,17 @@ In this case, you'll need to - *very carefully* - trust *all* proxies.
74122
#. Once you've guaranteed that traffic will only come from your trusted reverse
75123
proxies, configure Symfony to *always* trust incoming request::
76124

77-
// public/index.php
125+
.. config-block:: yaml
78126

79-
// ...
80-
Request::setTrustedProxies(
81-
// trust *all* requests (the 'REMOTE_ADDR' string is replaced at
82-
// run time by $_SERVER['REMOTE_ADDR'])
83-
['127.0.0.1', 'REMOTE_ADDR'],
127+
# config/packages/framework.yaml
128+
framework:
129+
# ...
130+
// trust *all* requests (the 'REMOTE_ADDR' string is replaced at
131+
// run time by $_SERVER['REMOTE_ADDR'])
132+
trusted_proxies: '127.0.0.1,REMOTE_ADDR'
84133

85-
// if you're using ELB, otherwise use a constant from above
86-
Request::HEADER_X_FORWARDED_AWS_ELB
87-
);
134+
// if you're using ELB, otherwise use another Request::HEADER-* constant
135+
trusted_headers: [!php/const Symfony\\Component\\HttpFoundation\\Request::HEADER_X_FORWARDED_AWS_ELB, '!x-forwarded-host', '!x-forwarded-prefix']
88136

89137
That's it! It's critical that you prevent traffic from all non-trusted sources.
90138
If you allow outside traffic, they could "spoof" their true IP address and
@@ -100,6 +148,12 @@ other information.
100148
# .env
101149
TRUSTED_PROXIES=127.0.0.1,REMOTE_ADDR
102150
151+
.. config-block:: yaml
152+
153+
# config/packages/framework.yaml
154+
framework:
155+
# ...
156+
trusted_proxies: '%env(TRUSTED_PROXIES)%'
103157

104158
If you are also using a reverse proxy on top of your load balancer (e.g.
105159
`CloudFront`_), calling ``$request->server->get('REMOTE_ADDR')`` won't be
@@ -111,11 +165,13 @@ trusted proxies.
111165
Custom Headers When Using a Reverse Proxy
112166
-----------------------------------------
113167

114-
Some reverse proxies (like `CloudFront`_ with ``CloudFront-Forwarded-Proto``) may force you to use a custom header.
115-
For instance you have ``Custom-Forwarded-Proto`` instead of ``X-Forwarded-Proto``.
168+
Some reverse proxies (like `CloudFront`_ with ``CloudFront-Forwarded-Proto``)
169+
may force you to use a custom header. For instance you have
170+
``Custom-Forwarded-Proto`` instead of ``X-Forwarded-Proto``.
116171

117-
In this case, you'll need to set the header ``X-Forwarded-Proto`` with the value of
118-
``Custom-Forwarded-Proto`` early enough in your application, i.e. before handling the request::
172+
In this case, you'll need to set the header ``X-Forwarded-Proto`` with the value
173+
of ``Custom-Forwarded-Proto`` early enough in your application, i.e. before
174+
handling the request::
119175

120176
// public/index.php
121177

reference/configuration/framework.rst

Lines changed: 22 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -284,6 +284,7 @@ Configuration
284284
* `logging`_
285285
* :ref:`paths <reference-translator-paths>`
286286

287+
* `trusted_headers`_
287288
* `trusted_hosts`_
288289
* `trusted_proxies`_
289290
* `validation`_
@@ -380,12 +381,32 @@ named ``kernel.http_method_override``.
380381
$request = Request::createFromGlobals();
381382
// ...
382383

384+
.. _reference-framework-trusted-headers:
385+
386+
trusted_headers
387+
~~~~~~~~~~~~~~~
388+
389+
.. versionadded:: 5.2
390+
391+
The ``trusted_headers`` option was introduced in Symfony 5.2.
392+
393+
The ``trusted_headers`` option is needed to configure which client information
394+
should be trusted (e.g. their host) when running Symfony behind a load balancer
395+
or a reverse proxy. See :doc:`/deployment/proxies`.
396+
383397
.. _reference-framework-trusted-proxies:
384398

385399
trusted_proxies
386400
~~~~~~~~~~~~~~~
387401

388-
The ``trusted_proxies`` option was removed in Symfony 3.3. See :doc:`/deployment/proxies`.
402+
.. versionadded:: 5.2
403+
404+
The ``trusted_headers`` option was reintroduced in Symfony 5.2 (it had been
405+
removed in Symfony 3.3).
406+
407+
The ``trusted_proxies`` option is needed to get precise information about the
408+
client (e.g. their IP address) when running Symfony behind a load balancer or a
409+
reverse proxy. See :doc:`/deployment/proxies`.
389410

390411
ide
391412
~~~

0 commit comments

Comments
 (0)