'Laravel 5.6 TrustedProxies error

I've upgraded from L5.5 to L5.6 today (updating Symfony components to v4 in the process). Also I've updated fideloper/proxy package to 4.0 as of official Laravel 5.6 upgrade guide.

After that I starts to getting this error: Type error: Argument 2 passed to Symfony\Component\HttpFoundation\Request::setTrustedProxies() must be of the type integer, array given, called in /var/www/html/vendor/fideloper/proxy/src/TrustProxies.php on line 54

Symfony 4's Symfony\Component\HttpFoundation\Request::setTrustedProxies() indeed expects integer (bitmask) as a 2nd argument:

/**
* Sets a list of trusted proxies.
*
* You should only list the reverse proxies that you manage directly.
*
* @param array $proxies          A list of trusted proxies
* @param int   $trustedHeaderSet A bit field of Request::HEADER_*, to set which headers to trust from your proxies
*
* @throws \InvalidArgumentException When $trustedHeaderSet is invalid
*/
public static function setTrustedProxies(array $proxies, int $trustedHeaderSet)
{
    self::$trustedProxies = $proxies;
    self::$trustedHeaderSet = $trustedHeaderSet;
}

and fideloper/proxy 4.0 is indeed gives an array instead of an integer into this function:

public function handle(Request $request, Closure $next)
{
    $request::setTrustedProxies([], $this->getTrustedHeaderNames()); // Reset trusted proxies between requests
    $this->setTrustedProxyIpAddresses($request);
    return $next($request);
}

and

/**
 * Retrieve trusted header name(s), falling back to defaults if config not set.
 *
 * @return array
 */
protected function getTrustedHeaderNames()
{
    return $this->headers ?: $this->config->get('trustedproxy.headers');
}

So I can't understand if this is bug in fideloper/proxy or I'm just missing something?



Solution 1:[1]

After some investigation (Winmerge comparison with a fresh install of Laravel 5.6) this comes down to a difference in the files app\Http\Middleware\TrustProxies.php:

Laravel 5.5:

namespace App\Http\Middleware;

use Illuminate\Http\Request;
use Fideloper\Proxy\TrustProxies as Middleware;

class TrustProxies extends Middleware
{
    /**
     * The trusted proxies for this application.
     *
     * @var array
     */
    protected $proxies;

    /**
     * The current proxy header mappings.
     *
     * @var array
     */
    protected $headers = [
        Request::HEADER_FORWARDED => 'FORWARDED',
        Request::HEADER_X_FORWARDED_FOR => 'X_FORWARDED_FOR',
        Request::HEADER_X_FORWARDED_HOST => 'X_FORWARDED_HOST',
        Request::HEADER_X_FORWARDED_PORT => 'X_FORWARDED_PORT',
        Request::HEADER_X_FORWARDED_PROTO => 'X_FORWARDED_PROTO',
    ];
}

Laravel 5.6:

namespace App\Http\Middleware;

use Illuminate\Http\Request;
use Fideloper\Proxy\TrustProxies as Middleware;

class TrustProxies extends Middleware
{
    /**
     * The trusted proxies for this application.
     *
     * @var array
     */
    protected $proxies;

    /**
     * The headers that should be used to detect proxies.
     *
     * @var string
     */
    protected $headers = Request::HEADER_X_FORWARDED_ALL;
}

Ergo, set protected $headers = Request::HEADER_X_FORWARDED_ALL; as per Laravel 5.6 version

Solution 2:[2]

Open app\Http\Middleware\TrustProxies.php.

Change the following

protected $headers = [
    Request::HEADER_FORWARDED => 'FORWARDED',
    Request::HEADER_X_FORWARDED_FOR => 'X_FORWARDED_FOR',
    Request::HEADER_X_FORWARDED_HOST => 'X_FORWARDED_HOST',
    Request::HEADER_X_FORWARDED_PORT => 'X_FORWARDED_PORT',
    Request::HEADER_X_FORWARDED_PROTO => 'X_FORWARDED_PROTO',
];

to

protected $headers = Request::HEADER_X_FORWARDED_ALL;

Solution 3:[3]

Please keep in mind also that when upgrading from Laravel 5.5 to 5.6 Laravel creates a new file called TrustProxies.php with the same namespace as TrustedProxies i.e "App\Http\Middleware\TrustProxies". In Laravel 5.6, the TrustedProxies.php file is correct as mentioned above.
The TrustProxies.php is not. But if they both exist in the same namespace, then Laravel will use the one that it finds first, and that is the TrustProxies.php file.

If you have both, then delete TrustProxies.php, and make sure that TrustedProxies.php has the correct changes as mentioned above.

Have an awesome day. Christian

Solution 4:[4]

If you are having this issue in Laravel 9.x or later, it is because Laravel has incorporated the package into the core framework and it's no longer needed.

The fideloper/TrustedProxy repo has added a note to it's readme instructing not to install the package on Laravel 9.x and instead follow the Laravel upgrade guide.

You can find the upgrade notes in the Laravel docs here under the heading "Trusted Proxies".

I found the change in the upgrade guide took me all of 30 seconds to complete!

Sources

This article follows the attribution requirements of Stack Overflow and is licensed under CC BY-SA 3.0.

Source: Stack Overflow

Solution Source
Solution 1 Inigo
Solution 2 aphoe
Solution 3 Christian Dominguez
Solution 4 ChrisVa