Laravel 5.6 TrustedProxies error

SkifAlef picture SkifAlef · Feb 8, 2018 · Viewed 16.4k times · Source

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?

Answer

Inigo picture Inigo · Feb 8, 2018

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