diff --git a/components/http_foundation/trusting_proxies.rst b/components/http_foundation/trusting_proxies.rst index fbe9b30cdee..2783f5ed521 100644 --- a/components/http_foundation/trusting_proxies.rst +++ b/components/http_foundation/trusting_proxies.rst @@ -11,9 +11,9 @@ Trusting Proxies 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. For example, the ``Host`` HTTP header is usually used to return -the requested host. But when you're behind a proxy, the true host may be -stored in a ``X-Forwarded-Host`` header. +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 a ``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 @@ -30,11 +30,19 @@ your proxy. // only trust proxy headers coming from this 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`; @@ -43,6 +51,7 @@ By default, the following proxy headers are trusted: 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'); @@ -51,9 +60,9 @@ can configure that header name via :method:`Symfony\\Component\\HttpFoundation\\ Not Trusting certain Headers ---------------------------- -By default, if you whitelist your proxy's IP address, then all four 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 ``X-Forwarded-Proto`` header, the default header is used - Request::setTrustedHeaderName(Request::HEADER_CLIENT_PROTO, ''); + // disables trusting the ``Forwarded`` header + Request::setTrustedHeaderName(Request::HEADER_FORWARDED, null); diff --git a/cookbook/cache/varnish.rst b/cookbook/cache/varnish.rst index e5bfcce1c95..31094a95d7a 100644 --- a/cookbook/cache/varnish.rst +++ b/cookbook/cache/varnish.rst @@ -24,6 +24,21 @@ Remember to configure :ref:`framework.trusted_proxies ` 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 { + remove 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:`the cookbook `. + .. _varnish-x-forwarded-headers: Routing and X-FORWARDED Headers diff --git a/cookbook/request/load_balancer_reverse_proxy.rst b/cookbook/request/load_balancer_reverse_proxy.rst index 343c9c35fa8..c247d661152 100644 --- a/cookbook/request/load_balancer_reverse_proxy.rst +++ b/cookbook/request/load_balancer_reverse_proxy.rst @@ -23,7 +23,7 @@ via HTTPS, the client's port and the hostname being requested. Solution: trusted_proxies ------------------------- -This is no problem, but you *do* need to tell Symfony that this is happening +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:: @@ -62,6 +62,9 @@ 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. +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. + 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. @@ -95,6 +98,29 @@ 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. +.. _cookbook-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 +malicious users to "spoof" their IP address. + My Reverse Proxy Uses Non-Standard (not X-Forwarded) Headers ------------------------------------------------------------