Fixing the trusted_proxies configuration for Symfony 3.3

The problem

If you upgrade an existing Symfony application to the new 3.3.0 version, you may see this error (depending on your application configuration):

The "framework.trusted_proxies" configuration key has been removed in Symfony 3.3.

The solution

Remove the framework.trusted_proxies option from your config file and call the Request::setTrustedProxies() method in your front controller.

For example, if your original config was the following:

# app/config/config.yml
framework:
    # ...
    trusted_proxies:  [192.0.0.1, 10.0.0.0/8]

Remove the trusted_proxies option entirely and add the following in the app.php file:

# web/app.php

// BEFORE
// ...
$kernel = new AppKernel('prod', false);
Request::setTrustedHeaderName(Request::HEADER_FORWARDED, null);
$request = Request::createFromGlobals();
// ...

// AFTER
// ...
$kernel = new AppKernel('prod', false);
Request::setTrustedHeaderName(Request::HEADER_FORWARDED, null);
Request::setTrustedProxies(['192.0.0.1', '10.0.0.0/8']);
$request = Request::createFromGlobals();
// ...

You can do this change right now because it also works in Symfony versions prior to 3.3. That way you'll be ready to upgrade your application. When Symfony 3.3 is released, you can simplify the above using the new second argument of setTrustedProxies() method:

# web/app.php

// BEFORE in Symfony 3.2
// ...
$kernel = new AppKernel('prod', false);
Request::setTrustedHeaderName(Request::HEADER_FORWARDED, null);
Request::setTrustedProxies(['192.0.0.1', '10.0.0.0/8']);
$request = Request::createFromGlobals();
// ...

// AFTER in Symfony 3.3
// ...
$kernel = new AppKernel('prod', false);
Request::setTrustedProxies(['192.0.0.1', '10.0.0.0/8'], Request::HEADER_X_FORWARDED_ALL);
$request = Request::createFromGlobals();
// ...

The explanation

Symfony project follows a backward compatibility policy that lets you upgrade across minor versions (e.g. from 2.7 to 2.8 or from 3.2 to 3.3) without breaking your applications.

The only exception to this policy is when breaking backward compatibility is the only way to fix a security issue. That's what happened in this case. A member of the Heroku team reported this problem to us and the only choice we had was to introduce this BC break.

Luckily the break is easy to fix and you can do it right now to make your applications forward compatible with Symfony 3.3.

Comments

[192.0.0.1, 10.0.0.0/8] should be ['192.0.0.1', '10.0.0.0/8'] in the PHP code, surely?
@Graham you are right. Thanks for the heads up. It's fixed now.
You are correct Graham 😛
The method setTrustedProxies in Request.php looks like this:

public static function setTrustedProxies(array $proxies)
{
self::$trustedProxies = $proxies;
}

What is the use of the ", Request::HEADER_X_FORWARDED_ALL" part of:

Request::setTrustedProxies(['192.0.0.1', '10.0.0.0/8'], Request::HEADER_X_FORWARDED_ALL);
what about setting different trusted proxies for different envs (dev, staging, ci, prod)? Hardcoding IPs is not always an options, config allowed to set this with parameters.yml file
Platform.sh has dynamic trusted proxies, so we need to call an api to get the proxies IP's.

Before this change it was easy as we just had to make a call when compiling the container and set the `trusted_proxies` config value.

With this change we have to call the API on every request in the front controller, so I guess we'll need to find a workaround and cache those IP's somewhere.
Sorry, I meant 'Fastly' (our CDN), not 'Platform.sh'.
The issue with the parameter is that it's too late: the request might have already been used when the FrameworkBundle configures it (e.g. when using HttpCache).
Since this is a security issue, we should be strict here.
For different envs, just use env vars + getenv() - or a deployment script that does the job.
@Nicolas, can we use explicit kernel boot before request to configure proxy from container params, if we do not use HttpCache? Or this would have other drawbacks?
I just had "trusted_proxies: ~" in my app/config/config.yml. So I can remove it and do nothing with my app.php?
@Georg that's right. I your "trusted_proxies" option was empty before, just remove it.
Thank you Javier!

Comments are closed.

To ensure that comments stay relevant, they are closed for old posts.