29

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?

DominikN.
  • 1,245
  • 1
  • 17
  • 27
SkifAlef
  • 292
  • 1
  • 3
  • 9
  • Same here. Project upgraded from Laravel 5.5 to 5.6, running vagrant homestead. Tried deleting vendor directory and running `composer install` again- same issue. Please post any solution. – Inigo Feb 08 '18 at 11:08
  • Stupid thing is: It's mentioned in the upgrade guide, but near the end. I scrolled through it expecting the most important change to be first, but no, the one that actually breaks your webinterface is near the end :) – Blizz Mar 12 '18 at 11:04
  • Did the same thing :) – SkifAlef Mar 13 '18 at 11:55

5 Answers5

33

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

Inigo
  • 8,110
  • 18
  • 62
  • 110
23

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;
aphoe
  • 2,586
  • 1
  • 27
  • 31
  • Useful from Laravel 5.6 up, I'm on Laravel 5.8 also helpful. Good luck and happy new year of 2021! – Osify Dec 30 '20 at 12:19
13

As stated in the upgrade guide, you need to set the $headers property in App\Http\Middleware\TrustProxies to a bit property.

The constants are defined in Symfony\Component\HttpFoundation\Request.

const HEADER_FORWARDED = 0b00001; // When using RFC 7239
const HEADER_X_FORWARDED_FOR = 0b00010;
const HEADER_X_FORWARDED_HOST = 0b00100;
const HEADER_X_FORWARDED_PROTO = 0b01000;
const HEADER_X_FORWARDED_PORT = 0b10000;
const HEADER_X_FORWARDED_ALL = 0b11110; // All "X-Forwarded-*" headers
const HEADER_X_FORWARDED_AWS_ELB = 0b11010; // AWS ELB doesn't send X-Forwarded-Host

In the upgrade guide, HEADER_X_FORWARDED_ALL is used but you can use a combination of the bit values.

Blizz
  • 8,082
  • 2
  • 33
  • 53
WJDev
  • 191
  • 1
  • 10
2

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

0

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!

ChrisVa
  • 153
  • 2
  • 7