From df63034200eacc9a74e6fa9c1c47ee6b2c454482 Mon Sep 17 00:00:00 2001 From: Jarek Jakubowski Date: Wed, 3 May 2017 16:12:49 +0200 Subject: [PATCH 1/6] Remove deprecated trusted_proxies config option --- reference/configuration/framework.rst | 36 ++------------------------- 1 file changed, 2 insertions(+), 34 deletions(-) diff --git a/reference/configuration/framework.rst b/reference/configuration/framework.rst index 5d5887c1450..fa04f67d9a5 100644 --- a/reference/configuration/framework.rst +++ b/reference/configuration/framework.rst @@ -22,7 +22,6 @@ Configuration * `secret`_ * `http_method_override`_ -* `trusted_proxies`_ * `ide`_ * `test`_ * `default_locale`_ @@ -183,44 +182,13 @@ named ``kernel.http_method_override``. $request = Request::createFromGlobals(); // ... + .. _reference-framework-trusted-proxies: trusted_proxies ~~~~~~~~~~~~~~~ -**type**: ``array`` - -Configures the IP addresses that should be trusted as proxies. For more -details, see :doc:`/request/load_balancer_reverse_proxy`. - -.. configuration-block:: - - .. code-block:: yaml - - # app/config/config.yml - framework: - trusted_proxies: [192.0.0.1, 10.0.0.0/8] - - .. code-block:: xml - - - - - - - - - .. code-block:: php - - // app/config/config.php - $container->loadFromExtension('framework', array( - 'trusted_proxies' => array('192.0.0.1', '10.0.0.0/8'), - )); +The ``trusted_proxies`` option was removed in Symfony 3.3. See :doc:`/request/load_balancer_reverse_proxy`. ide ~~~ From 1825c83f4b6781418a4fd0b609183ff5418e9848 Mon Sep 17 00:00:00 2001 From: Jarek Jakubowski Date: Wed, 3 May 2017 16:23:12 +0200 Subject: [PATCH 2/6] Remove deprecated trusted_proxies config option --- request/load_balancer_reverse_proxy.rst | 35 +++++-------------------- 1 file changed, 7 insertions(+), 28 deletions(-) diff --git a/request/load_balancer_reverse_proxy.rst b/request/load_balancer_reverse_proxy.rst index e1a4370ed56..4424848c6d2 100644 --- a/request/load_balancer_reverse_proxy.rst +++ b/request/load_balancer_reverse_proxy.rst @@ -25,40 +25,19 @@ and which reverse proxy IP addresses will be doing this type of thing: .. configuration-block:: - .. code-block:: yaml - - # app/config/config.yml - # ... - framework: - trusted_proxies: [192.0.0.1, 10.0.0.0/8] - - .. code-block:: xml - - - - + .. code-block:: diff - - - - + // web/app.php - .. code-block:: php + // ... + $request = Request::createFromGlobals(); + + Request::setTrustedProxies(['127.0.0.1', '10.0.0.0/8']); - // app/config/config.php - $container->loadFromExtension('framework', array( - 'trusted_proxies' => array('192.0.0.1', '10.0.0.0/8'), - )); + // ... In this example, you're saying that your reverse proxy (or proxies) has the IP address ``192.0.0.1`` or matches the range of IP addresses that use -the CIDR notation ``10.0.0.0/8``. For more details, see the -:ref:`framework.trusted_proxies ` option. +the CIDR notation ``10.0.0.0/8``. You are also saying that you trust that the proxy does not send conflicting headers, e.g. sending both ``X-Forwarded-For`` and ``Forwarded`` in the same From 3632c08ecd259b975e7df2ef456fac73a6b94921 Mon Sep 17 00:00:00 2001 From: Christian Flothmann Date: Fri, 12 May 2017 17:23:16 +0200 Subject: [PATCH 3/6] replace diff code block with PHP code block --- request/load_balancer_reverse_proxy.rst | 15 ++++++++------- 1 file changed, 8 insertions(+), 7 deletions(-) diff --git a/request/load_balancer_reverse_proxy.rst b/request/load_balancer_reverse_proxy.rst index 4424848c6d2..1e44810a241 100644 --- a/request/load_balancer_reverse_proxy.rst +++ b/request/load_balancer_reverse_proxy.rst @@ -23,17 +23,18 @@ Solution: trusted_proxies This is no problem, but you *do* need to tell Symfony what is happening and which reverse proxy IP addresses will be doing this type of thing: -.. configuration-block:: +.. code-block:: php - .. code-block:: diff + // web/app.php - // web/app.php + // ... + $request = Request::createFromGlobals(); - // ... - $request = Request::createFromGlobals(); - + Request::setTrustedProxies(['127.0.0.1', '10.0.0.0/8']); + // use the setTrustedProxies() method to tell Symfony + // about your reverse proxy IP addresses + Request::setTrustedProxies(['127.0.0.1', '10.0.0.0/8']); - // ... + // ... In this example, you're saying that your reverse proxy (or proxies) has the IP address ``192.0.0.1`` or matches the range of IP addresses that use From 2f83164d135b3260b23ec8c9c39a41b8983012f4 Mon Sep 17 00:00:00 2001 From: Christian Flothmann Date: Fri, 12 May 2017 17:31:21 +0200 Subject: [PATCH 4/6] replace trusted_proxies reference --- http_cache/varnish.rst | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/http_cache/varnish.rst b/http_cache/varnish.rst index 64df73241cb..2e5dc6c41f1 100644 --- a/http_cache/varnish.rst +++ b/http_cache/varnish.rst @@ -20,9 +20,9 @@ Varnish automatically forwards the IP as ``X-Forwarded-For`` and leaves the trusted proxy, Symfony will see all requests as coming through insecure HTTP connections from the Varnish host instead of the real client. -Remember to configure :ref:`framework.trusted_proxies ` -in the Symfony configuration so that Varnish is seen as a trusted proxy and the -:ref:`X-Forwarded ` headers are used. +Remember to call the :method:`Symfony\\Component\\HttpFoundation\\Request::setTrustedProxies` +method in your front controller so that Varnish is seen as a trusted proxy +and the :ref:`X-Forwarded ` headers are used. Varnish, in its default configuration, sends the ``X-Forwarded-For`` header but does not filter out the ``Forwarded`` header. If you have access to the Varnish From 45b419d943c57062e464c3b57e1a25c56d55e81a Mon Sep 17 00:00:00 2001 From: Ryan Weaver Date: Sat, 27 May 2017 13:58:21 -0400 Subject: [PATCH 5/6] Adding second argument to setTrustedProxies() and removing old information --- _build/redirection_map | 1 + .../http_foundation/trusting_proxies.rst | 65 ------------- http_cache/varnish.rst | 17 +--- request/load_balancer_reverse_proxy.rst | 95 ++++++------------- 4 files changed, 31 insertions(+), 147 deletions(-) delete mode 100644 components/http_foundation/trusting_proxies.rst diff --git a/_build/redirection_map b/_build/redirection_map index 3ce14efbb69..ad3565820f1 100644 --- a/_build/redirection_map +++ b/_build/redirection_map @@ -338,3 +338,4 @@ /security/target_path /security /service_container/third_party /service_container /templating/templating_service /templates +/components/http_foundation/trusting_proxies /request/load_balancer_reverse_proxy diff --git a/components/http_foundation/trusting_proxies.rst b/components/http_foundation/trusting_proxies.rst deleted file mode 100644 index e97404e0a0c..00000000000 --- a/components/http_foundation/trusting_proxies.rst +++ /dev/null @@ -1,65 +0,0 @@ -.. index:: - single: Request; Trusted Proxies - -Trusting Proxies -================ - -.. tip:: - - If you're using the Symfony Framework, start by reading - :doc:`/request/load_balancer_reverse_proxy`. - -If you find yourself behind some sort of proxy - like a load balancer - then -certain header information may be sent to you using special ``X-Forwarded-*`` -headers or the ``Forwarded`` header. For example, the ``Host`` HTTP header is -usually used to return the requested host. But when you're behind a proxy, -the actual host may be stored in an ``X-Forwarded-Host`` header. - -Since HTTP headers can be spoofed, Symfony does *not* trust these proxy -headers by default. If you are behind a proxy, you should manually whitelist -your proxy as follows: - -.. code-block:: php - - use Symfony\Component\HttpFoundation\Request; - - // put this code as early as possible in your application (e.g. in your - // front controller) to only trust proxy headers coming from these IP addresses - Request::setTrustedProxies(array('192.0.0.1', '10.0.0.0/8')); - -You should also make sure that your proxy filters unauthorized use of these -headers, e.g. if a proxy natively uses the ``X-Forwarded-For`` header, it -should not allow clients to send ``Forwarded`` headers to Symfony. - -If your proxy does not filter headers appropriately, you need to configure -Symfony not to trust the headers your proxy does not filter (see below). - -Configuring Header Names ------------------------- - -By default, the following proxy headers are trusted: - -* ``Forwarded`` Used in :method:`Symfony\\Component\\HttpFoundation\\Request::getClientIp`; -* ``X-Forwarded-For`` Used in :method:`Symfony\\Component\\HttpFoundation\\Request::getClientIp`; -* ``X-Forwarded-Host`` Used in :method:`Symfony\\Component\\HttpFoundation\\Request::getHost`; -* ``X-Forwarded-Port`` Used in :method:`Symfony\\Component\\HttpFoundation\\Request::getPort`; -* ``X-Forwarded-Proto`` Used in :method:`Symfony\\Component\\HttpFoundation\\Request::getScheme` and :method:`Symfony\\Component\\HttpFoundation\\Request::isSecure`; - -If your reverse proxy uses a different header name for any of these, you -can configure that header name via :method:`Symfony\\Component\\HttpFoundation\\Request::setTrustedHeaderName`:: - - Request::setTrustedHeaderName(Request::HEADER_FORWARDED, 'X-Forwarded'); - Request::setTrustedHeaderName(Request::HEADER_CLIENT_IP, 'X-Proxy-For'); - Request::setTrustedHeaderName(Request::HEADER_CLIENT_HOST, 'X-Proxy-Host'); - Request::setTrustedHeaderName(Request::HEADER_CLIENT_PORT, 'X-Proxy-Port'); - Request::setTrustedHeaderName(Request::HEADER_CLIENT_PROTO, 'X-Proxy-Proto'); - -Not Trusting certain Headers ----------------------------- - -By default, if you whitelist your proxy's IP address, then all five headers -listed above are trusted. If you need to trust some of these headers but -not others, you can do that as well:: - - // disables trusting the ``Forwarded`` header - Request::setTrustedHeaderName(Request::HEADER_FORWARDED, null); diff --git a/http_cache/varnish.rst b/http_cache/varnish.rst index 2e5dc6c41f1..0b00fbac2d9 100644 --- a/http_cache/varnish.rst +++ b/http_cache/varnish.rst @@ -20,25 +20,10 @@ Varnish automatically forwards the IP as ``X-Forwarded-For`` and leaves the trusted proxy, Symfony will see all requests as coming through insecure HTTP connections from the Varnish host instead of the real client. -Remember to call the :method:`Symfony\\Component\\HttpFoundation\\Request::setTrustedProxies` +Remember to call the :ref:`Request::setTrustedProxies() ` method in your front controller so that Varnish is seen as a trusted proxy and the :ref:`X-Forwarded ` headers are used. -Varnish, in its default configuration, sends the ``X-Forwarded-For`` header but -does not filter out the ``Forwarded`` header. If you have access to the Varnish -configuration file, you can configure Varnish to remove the ``Forwarded`` -header: - -.. code-block:: varnish4 - - sub vcl_recv { - unset req.http.Forwarded; - } - -If you do not have access to your Varnish configuration, you can instead -configure Symfony to distrust the ``Forwarded`` header as detailed in -:ref:`How to Configure Symfony to Work behind a Load Balancer or a Reverse Proxy `. - .. _varnish-x-forwarded-headers: Routing and X-FORWARDED Headers diff --git a/request/load_balancer_reverse_proxy.rst b/request/load_balancer_reverse_proxy.rst index 1e44810a241..d80c10ea2f5 100644 --- a/request/load_balancer_reverse_proxy.rst +++ b/request/load_balancer_reverse_proxy.rst @@ -7,21 +7,22 @@ an AWS Elastic Load Balancer) or a reverse proxy (e.g. Varnish for For the most part, this doesn't cause any problems with Symfony. But, when a request passes through a proxy, certain request information is sent using -either the standard ``Forwarded`` header or non-standard special ``X-Forwarded-*`` -headers. For example, instead of reading the ``REMOTE_ADDR`` header (which -will now be the IP address of your reverse proxy), the user's true IP will be -stored in a standard ``Forwarded: for="..."`` header or a non standard -``X-Forwarded-For`` header. +either the standard ``Forwarded`` header or ``X-Forwarded-*`` headers. For example, +instead of reading the ``REMOTE_ADDR`` header (which will now be the IP address of +your reverse proxy), the user's true IP will be stored in a standard ``Forwarded: for="..."`` +header or a ``X-Forwarded-For`` header. If you don't configure Symfony to look for these headers, you'll get incorrect information about the client's IP address, whether or not the client is connecting via HTTPS, the client's port and the hostname being requested. -Solution: trusted_proxies -------------------------- +.. _request-set-trusted-proxies: -This is no problem, but you *do* need to tell Symfony what is happening -and which reverse proxy IP addresses will be doing this type of thing: +Solution: setTrustedProxies() +----------------------------- + +To fix this, you need to tell Symfony which reverse proxy IP addresses to trust +and what headers your reverse proxy uses to send information: .. code-block:: php @@ -30,23 +31,21 @@ and which reverse proxy IP addresses will be doing this type of thing: // ... $request = Request::createFromGlobals(); - // use the setTrustedProxies() method to tell Symfony - // about your reverse proxy IP addresses - Request::setTrustedProxies(['127.0.0.1', '10.0.0.0/8']); - - // ... + // tell Symfony about your revers proxy + Request::setTrustedProxies( + // the ip address (or range) of your proxy + ['192.0.0.1', '10.0.0.0/8'], -In this example, you're saying that your reverse proxy (or proxies) has -the IP address ``192.0.0.1`` or matches the range of IP addresses that use -the CIDR notation ``10.0.0.0/8``. + // trust *all* "X-Forwarded-*" headers + Request::HEADER_X_FORWARDED_ALL -You are also saying that you trust that the proxy does not send conflicting -headers, e.g. sending both ``X-Forwarded-For`` and ``Forwarded`` in the same -request. + // or, if your proxy instead uses the "Forwarded" header + // Request::HEADER_FORWARDED + ); -That's it! Symfony will now look for the correct headers to get information -like the client's IP address, host, port and whether the request is -using HTTPS. +The Request object has several ``Request::HEADER_*`` constants that control exactly +*which* headers from your reverse proxy are trusted. The argument is a bit field, +so you can also pass your own value (e.g. ``0b00110``). But what if the IP of my Reverse Proxy Changes Constantly! ---------------------------------------------------------- @@ -59,60 +58,24 @@ In this case, you'll need to - *very carefully* - trust *all* proxies. other than your load balancers. For AWS, this can be done with `security groups`_. #. Once you've guaranteed that traffic will only come from your trusted reverse - proxies, configure Symfony to *always* trust incoming request. This is - done inside of your front controller: + proxies, configure Symfony to *always* trust incoming request: .. code-block:: diff // web/app.php // ... - $request = Request::createFromGlobals(); - + Request::setTrustedProxies(array('127.0.0.1', $request->server->get('REMOTE_ADDR'))); - - // ... + Request::setTrustedProxies( + // trust *all* requests + array('127.0.0.1', $request->server->get('REMOTE_ADDR')), -#. Ensure that the trusted_proxies setting in your ``app/config/config.yml`` - is not set or it will overwrite the ``setTrustedProxies()`` call above. + // if you're using ELB, otherwise use a constant from above + Request::HEADER_X_FORWARDED_AWS_ELB + ); That's it! It's critical that you prevent traffic from all non-trusted sources. If you allow outside traffic, they could "spoof" their true IP address and other information. -.. _request-untrust-header: - -My Reverse Proxy Sends X-Forwarded-For but Does not Filter the Forwarded Header -------------------------------------------------------------------------------- - -Many popular proxy implementations do not yet support the ``Forwarded`` header -and do not filter it by default. Ideally, you would configure this in your -proxy. If this is not possible, you can tell Symfony to distrust the ``Forwarded`` -header, while still trusting your proxy's ``X-Forwarded-For`` header. - -This is done inside of your front controller:: - - // web/app.php - - // ... - Request::setTrustedHeaderName(Request::HEADER_FORWARDED, null); - - $response = $kernel->handle($request); - // ... - -Configuring the proxy server trust is very important, as not doing so will -allow malicious users to "spoof" their IP address. - -My Reverse Proxy Uses Non-Standard (not X-Forwarded) Headers ------------------------------------------------------------- - -Although `RFC 7239`_ recently defined a standard ``Forwarded`` header to disclose -all proxy information, most reverse proxies store information in non-standard -``X-Forwarded-*`` headers. - -But if your reverse proxy uses other non-standard header names, you can configure -these (see ":doc:`/components/http_foundation/trusting_proxies`"). - -The code for doing this will need to live in your front controller (e.g. ``web/app.php``). - .. _`security groups`: http://docs.aws.amazon.com/elasticloadbalancing/latest/classic/elb-security-groups.html .. _`RFC 7239`: http://tools.ietf.org/html/rfc7239 From c7087bfa4d83e393a2ac3daaacb1499fcd5bd804 Mon Sep 17 00:00:00 2001 From: Ryan Weaver Date: Tue, 30 May 2017 09:58:13 -0400 Subject: [PATCH 6/6] tweaks thanks to review --- http_cache/varnish.rst | 2 +- reference/configuration/framework.rst | 1 - request/load_balancer_reverse_proxy.rst | 7 +++++-- 3 files changed, 6 insertions(+), 4 deletions(-) diff --git a/http_cache/varnish.rst b/http_cache/varnish.rst index 0b00fbac2d9..43d4473b9f2 100644 --- a/http_cache/varnish.rst +++ b/http_cache/varnish.rst @@ -22,7 +22,7 @@ connections from the Varnish host instead of the real client. Remember to call the :ref:`Request::setTrustedProxies() ` method in your front controller so that Varnish is seen as a trusted proxy -and the :ref:`X-Forwarded ` headers are used. +and the :ref:`X-Forwarded-* ` headers are used. .. _varnish-x-forwarded-headers: diff --git a/reference/configuration/framework.rst b/reference/configuration/framework.rst index fa04f67d9a5..8249ec12eec 100644 --- a/reference/configuration/framework.rst +++ b/reference/configuration/framework.rst @@ -182,7 +182,6 @@ named ``kernel.http_method_override``. $request = Request::createFromGlobals(); // ... - .. _reference-framework-trusted-proxies: trusted_proxies diff --git a/request/load_balancer_reverse_proxy.rst b/request/load_balancer_reverse_proxy.rst index d80c10ea2f5..f656d0e0527 100644 --- a/request/load_balancer_reverse_proxy.rst +++ b/request/load_balancer_reverse_proxy.rst @@ -31,9 +31,9 @@ and what headers your reverse proxy uses to send information: // ... $request = Request::createFromGlobals(); - // tell Symfony about your revers proxy + // tell Symfony about your reverse proxy Request::setTrustedProxies( - // the ip address (or range) of your proxy + // the IP address (or range) of your proxy ['192.0.0.1', '10.0.0.0/8'], // trust *all* "X-Forwarded-*" headers @@ -41,6 +41,9 @@ and what headers your reverse proxy uses to send information: // or, if your proxy instead uses the "Forwarded" header // Request::HEADER_FORWARDED + + // or, if you're using AWS ELB + // Request::HEADER_X_FORWARDED_AWS_ELB ); The Request object has several ``Request::HEADER_*`` constants that control exactly