Laravel Proxy Package for handling sessions when behind load balancers or other intermediaries.

Related tags

Laravel TrustedProxy
Overview

Laravel Trusted Proxies

Build Status Total Downloads

Setting a trusted proxy allows for correct URL generation, redirecting, session handling and logging in Laravel when behind a reverse proxy such as a load balancer or cache.


Installation

Laravel 5.5+ comes with this package. If you are using Laravel 5.5 or greater, you do not need to add this to your project separately.

Laravel 5.0 - 5.4

To install Trusted Proxy, use:

composer require fideloper/proxy:^3.3

Laravel 4

composer require fideloper/proxy:^2.0

Setup

Refer to the docs above for using Trusted Proxy in Laravel 5.5+. For Laravel 4.0 - 5.4, refer to the wiki.

What Does This Do?

Setting a trusted proxy allows for correct URL generation, redirecting, session handling and logging in Laravel when behind a reverse proxy.

This is useful if your web servers sit behind a load balancer (Nginx, HAProxy, Envoy, ELB/ALB, etc), HTTP cache (CloudFlare, Squid, Varnish, etc), or other intermediary (reverse) proxy.

How Does This Work?

Applications behind a reverse proxy typically read some HTTP headers such as X-Forwarded, X-Forwarded-For, X-Forwarded-Proto (and more) to know about the real end-client making an HTTP request.

If those headers were not set, then the application code would think every incoming HTTP request would be from the proxy.

Laravel (technically the Symfony HTTP base classes) have a concept of a "trusted proxy", where those X-Forwarded headers will only be used if the source IP address of the request is known. In other words, it only trusts those headers if the proxy is trusted.

This package creates an easier interface to that option. You can set the IP addresses of the proxies (that the application would see, so it may be a private network IP address), and the Symfony HTTP classes will know to use the X-Forwarded headers if an HTTP requets containing those headers was from the trusted proxy.

Why Does This Matter?

A very common load balancing approach is to send https:// requests to a load balancer, but send http:// requests to the application servers behind the load balancer.

For example, you may send a request in your browser to https://example.org. The load balancer, in turn, might send requests to an application server at http://192.168.1.23.

What if that server returns a redirect, or generates an asset url? The users's browser would get back a redirect or HTML that includes http://192.168.1.23 in it, which is clearly wrong.

What happens is that the application thinks its hostname is 192.168.1.23 and the schema is http://. It doesn't know that the end client used https://example.org for its web request.

So the application needs to know to read the X-Forwarded headers to get the correct request details (schema https://, host example.org).

Laravel/Symfony automatically reads those headers, but only if the trusted proxy configuration is set to "trust" the load balancer/reverse proxy.

Note: Many of us use hosted load balancers/proxies such as AWS ELB/ALB, etc. We don't know the IP address of those reverse proxies, and so you need to trusted all proxies in that case.

The trade-off there is running the security risk of allowing people to potentially spoof the X-Forwarded headers.

IP Addresses by Service

This Wiki page has a list of popular services and their IP addresses of their servers, if available. Any updates or suggestions are welcome!

Comments
  • Symfony Request.php setTrustedProxies Requires Two Arguments

    Symfony Request.php setTrustedProxies Requires Two Arguments

    I see that the call to $request->setTrustedProxies() provides only 1 argument as seen below:

    private function setTrustedProxyIpAddressesToTheCallingIp($request) {
        $request->setTrustedProxies($request->getClientIps());
    }
    

    but setTrustedProxies() now requires two arguments: https://github.com/symfony/http-foundation/blob/master/Request.php#L587

    Unless I am mistaken, TrustedProxy, as is, is no longer working.

    opened by eduardoagarcia 24
  • Problem with redirect() from Laravel being always http

    Problem with redirect() from Laravel being always http

    If I try to wget the root folder of my app page, then it will redirect me to the /login page via Laravel's redirect() helper method.

    I have a web server behing a load balancer that is the endopoint for SSL. When I open the root url of my app, I get redirected to the /login page if not logged in, an everything works fine and the final result is as expected (I get redirected properly)

    But what happens behind the scene is the following:

    1. I ask for https://app.workstack.io
    2. Load balancer forwards it to the web server that responds with a redirect to HTTP://app.workstack.io/login
    3. Request is sent to the Load Balancer that redirects again to HTTPS://app.workstack.io/login
    4. Finally the request goes through the web server and I output the login page.

    My question is: Is it possible in some way to avoid the extra redirect from http to https? I think it's a similar problem like when using the url() helper, where you need to replace it with secure_url() or it will be output with http instead of https. Is there a way to tell Laravel to use always https by default for all the url generated by its helper methods? (url(), redirect(), etc.)

    I copy here the wget of the request so that it get be more clear

    wget https://app.workstack.io --2016-06-09 22:08:37-- https://app.workstack.io/ Resolving app.workstack.io (app.workstack.io)... 174.143.185.9 Connecting to app.workstack.io (app.workstack.io)|174.143.185.9|:443... connected. HTTP request sent, awaiting response... 302 Found Location: http://app.workstack.io/login [following] --2016-06-09 22:08:37-- http://app.workstack.io/login Connecting to app.workstack.io (app.workstack.io)|174.143.185.9|:80... connected. HTTP request sent, awaiting response... 301 Moved Permanently Location: https://app.workstack.io/login [following] --2016-06-09 22:08:37-- https://app.workstack.io/login Connecting to app.workstack.io (app.workstack.io)|174.143.185.9|:443... connected. HTTP request sent, awaiting response... 200 OK Length: unspecified [text/html] Saving to: ‘index.html.3’

    Thanks a lot for this awesome library btw! :)

    opened by crash13override 16
  • Multiple layers of load balancers in 4.0

    Multiple layers of load balancers in 4.0

    Our setup has multiple LB IP addresses, first a local one 10.* and then a public one 130.*. Lastly the users IP. This means that TrustedProxy should filter out 10.* and 130.*, but no matter what I do, it only filters out the first IP.

    Everything worked correctly in version 3.*, but after upgrading to 4.*, it stopped working. Doesn't TrustedProxy support multiple layers of load balancers anymore?

    Our environment is Google Cloud Platform with Laravel 5.6 and PHP 7.1.

    opened by niclashedam 14
  • Request ips wrong order when using a load balancer

    Request ips wrong order when using a load balancer

    Hi, I recently upgrade one application from Laravel 5.2 to Laravel 5.7 Before the upgrade I was using this library (v3.3) with the configuration below

        'proxies' => '**',
    ...
        'headers' => [
            (defined('Illuminate\Http\Request::HEADER_FORWARDED') ? Illuminate\Http\Request::HEADER_FORWARDED : 'forwarded') => null,
            Illuminate\Http\Request::HEADER_CLIENT_IP    => 'X_FORWARDED_FOR',
            Illuminate\Http\Request::HEADER_CLIENT_HOST  => null,
            Illuminate\Http\Request::HEADER_CLIENT_PROTO => 'X_FORWARDED_PROTO',
            Illuminate\Http\Request::HEADER_CLIENT_PORT  => 'X_FORWARDED_PORT',
        ]
    

    After the upgrade, I added the TrustProxies middleware below

    <?php
    
    namespace App\Http\Middleware;
    
    use Fideloper\Proxy\TrustProxies as Middleware;
    use Illuminate\Http\Request;
    
    class TrustProxies extends Middleware
    {
        /**
         * The trusted proxies for this application.
         *
         * @var array
         */
        protected $proxies = '**';
    
        /**
         * The headers that should be used to detect proxies.
         *
         * @var int
         */
        protected $headers = Request::HEADER_X_FORWARDED_AWS_ELB;
    }
    

    The issue I am having might not be related to this, but basically after the upgrade

    $request->ip() // the ec2 ip
    $request->ips() // [ec2 ip, client ip]
    

    It seems the order or the ips is inverted, I should be getting first the client ip, then any other ip.

    Is this a configuration issue on my side or is there anything else I am missing?

    opened by peppeocchi 13
  • how to set custom HEADER_X_FORWARD in 4.0

    how to set custom HEADER_X_FORWARD in 4.0

    Hi,

    Prior to 4.0, i could do something like this in config/trustproxy.php :

    'headers' => [
        (defined('Illuminate\Http\Request::HEADER_FORWARDED') ? Illuminate\Http\Request::HEADER_FORWARDED : 'forwarded') => 'FORWARDED',
        Illuminate\Http\Request::HEADER_CLIENT_IP    => 'X_FORWARDED_FOR',
        Illuminate\Http\Request::HEADER_CLIENT_HOST  => 'X_FORWARDED_HOST',
        Illuminate\Http\Request::HEADER_CLIENT_PROTO => 'X_FORWARDED_PROTO_CUSTOM',
        Illuminate\Http\Request::HEADER_CLIENT_PORT  => 'X_FORWARDED_PORT_CUSTOM',
    ]
    

    But with 4.0 i can't find a way to specify custom names for HEADER_CLIENT_PORT and HEADER_CLIENT_PROTO

    Does someone know how to deal with this issue ?

    thx

    opened by olivM 13
  • Non-Numeric Value encountered

    Non-Numeric Value encountered

    I had been up and running with you proxy for about a month now on an AWS box with load balancer and Laravel on backend. After an upgrade (at 3.3 now) now getting an error:

    ErrorException in TrustProxies.php line 159:
    A non-numeric value encountered
    in TrustProxies.php line 159
    at HandleExceptions->handleError('2', 'A non-numeric value encountered', '/home/forge/isdb.io/code/Laravel/vendor/fideloper/proxy/src/TrustProxies.php', '159', array('set' => '0', 'key' => 'forwarded')) in /home/forge/isdb.io/code/Laravel/vendor/fideloper/proxy/src/TrustProxies.php line 159
    at TrustProxies->Fideloper\Proxy\{closure}('0', 'forwarded')
    

    Scratching my head with no clue whats happening....any help would be appreciated.

    Thx

    DJK

    opened by kapsoft 12
  • adding support for AWS ELB. Accept IPs separated by comma.

    adding support for AWS ELB. Accept IPs separated by comma.

    1. Accept IPs separated by comma.
      • Probably In a project like Laravel you need to add this config to the .env file and array is not supported in .env
    TRUSTEDPROXY_PROXIES='192.168.1.1, 192.168.1.2'
    
    'proxies' => env('TRUSTEDPROXY_PROXIES', null),
    
    1. Accept headers as a string.
      • Probably In a project like Laravel you need to add this config to the .env file and you can pass the header you want to use as a string:
    TRUSTEDPROXY_HEADERS='HEADER_X_FORWARDED_AWS_ELB'
    
    'headers' => env('TRUSTEDPROXY_HEADERS', 'HEADER_X_FORWARDED_ALL'),
    
    opened by rrpadilla 11
  • array_keys() error

    array_keys() error

    Hello I've just upgraded an app from 5.4.36 to 5.5 (via Laravel Shift, with PHP 7.1.13 on Homestead vagrant box.)

    I'm getting this E_WARNING for vendor/fideloper/proxy/src/TrustProxies.php:162, even though to the best of my knowledge I've not configured load balancing etc. at all:

    array_keys() expects parameter 1 to be array, integer given

        protected function getTrustedHeaderSet()
        {
            $trustedHeaderNames = $this->getTrustedHeaderNames();
            $headerKeys = array_keys($this->getTrustedHeaderNames());
    
    

    Composer has fideloper/proxy (3.3.4) (specified as "~3.3")

    I can fix it by simply casting to an array with:

    $headerKeys = array_keys((array) $this->getTrustedHeaderNames());

    Is that adequate? (I know nothing about your package...)

    (Thanks)

    opened by wturrell 11
  • AWS EBS and Lumen 5.4 - LB IP

    AWS EBS and Lumen 5.4 - LB IP

    Hi,

    I'm using Elastic Beanstalk (with a load balancer) and Lumen 5.4 - I followed the steps (code included below) however, when calling $request->getClientIp(); I'm still getting the load balancer's IP;

    bootstrap/app.php

     $app->middleware([
         // other middleware
         'Fideloper\Proxy\TrustProxies'
     ]);
    
    // other service providers
    $app->register(Fideloper\Proxy\TrustedProxyServiceProvider::class);
    

    config/trustedproxy.php

    <?php
    
    return [
        'proxies' => [
            '*',
        ],
    
        // These are defaults already set in the config:
        'headers' => [
            (defined('Illuminate\Http\Request::HEADER_FORWARDED') ? Illuminate\Http\Request::HEADER_FORWARDED : 'forwarded') => null,
            \Illuminate\Http\Request::HEADER_CLIENT_IP    => 'X_FORWARDED_FOR',
            \Illuminate\Http\Request::HEADER_CLIENT_HOST  => null,
            \Illuminate\Http\Request::HEADER_CLIENT_PROTO => 'X_FORWARDED_PROTO',
            \Illuminate\Http\Request::HEADER_CLIENT_PORT  => 'X_FORWARDED_PORT',
        ]
    ];
    

    What's actually being forwarded;

    [HTTP_X_FORWARDED_FOR] => 141.105.x.x (real IP)
    [HTTP_X_FORWARDED_PORT] => 80
    [HTTP_X_FORWARDED_PROTO] => http
    

    Am I missing something from this configuration?

    opened by andrew-s 11
  • [Idea] Load the trusted proxies from an environment variable

    [Idea] Load the trusted proxies from an environment variable

    It would be useful to be able to pass a list of trusted proxies via an environment variable, for example TRUSTED_PROXIES=192.168.0.10,172.10.0.4.

    My specific use case is running CachetHQ. They trust CloudFlare's IPs by default, but I need to add my local nginx reverse proxy IP to that list. My only option now is to change that file directly, which isn't ideal.

    Although the reason I'd like this is very specific, there're other cases where it would be useful. For example, trusting different proxies in different environments (dev, qa, staging, production).

    What do you think?

    opened by vitorbaptista 11
  • laravel 5.4 behind an IBM load balancer

    laravel 5.4 behind an IBM load balancer

    Hi!

    I'm running 2 laravels behind an IBM Load Balancer and i cant get Trustedproxy to work. I've tried all the configs mentioned in previous issues but i cant make it work.

    thanks!

    opened by sgdmediagroup 9
  • ⚠️ ➡️➡️➡️ Laravel 9 issues: Read this before making an issue ⬅️⬅️⬅️

    ⚠️ ➡️➡️➡️ Laravel 9 issues: Read this before making an issue ⬅️⬅️⬅️

    Laravel 9 has incorporated this package into the core of Laravel.

    See the upgrade guide here: https://laravel.com/docs/9.x/upgrade, search for Trusted Proxies

    image

    opened by fideloper 15
  • Addressed how wildcards are handled so it functions with multiple load balancers

    Addressed how wildcards are handled so it functions with multiple load balancers

    This could either be an issue with the documentation and comments, or it could be an issue with the way that wildcards are being handled. Because of that, I have only created this as a draft pull request to prompt discussion on the matter and in the hope that either the code or the documentation are fixed.

    From the documentation and code comments, I am concluding that the intent of using * as a wildcard is to trust all proxies, however; all it currently appears to do is trust the calling IP address and not every IP in the chain.

    For example, if a request goes through the following flow CloudFlare > DigitalOcean > Kubernetes one may end up with the something akin to 123.456.0.1, 172.68.0.1, 104.16.0.1 for the value of $_SERVER['HTTP_X_FORWARDED_FOR'] where 123.456.0.1 is the actual source IP. When using * as a wildcard, this package erroneously returns 104.16.0.1 when calling request()->ip() instead of the expected result.

    This pull request addresses this issue and corrects the order of IPs in tests so that they match what's received in real world scenarios. The reversed IP addresses are also an indicator that this is a code issue, that is, assuming that wasn't the intent, and if it was the intent, then that would ideally be handled in a separate code block or perhaps some comments added to indicate so.

    Other open issues also mention this, for example, https://github.com/fideloper/TrustedProxy/issues/115 and https://github.com/fideloper/TrustedProxy/issues/107

    opened by simonworkhouse 2
  • Support custom trusted header bitmasks

    Support custom trusted header bitmasks

    This PR adds support for custom bitmasks, which are necessary if your load balancer doesn't support all X-Forwarded-* headers and doesn't support the same subset of X-Forwarded-* headers that AWS ELB uses. I personally ran into this while using ngrok via valet share, which doesn't send HEADER_X_FORWARDED_PORT.

    opened by matt-allan 3
  •  fix

    fix "failed to open required file" for config file

    This will fix "failed to open required file" When we use this package (with laravel) inside phar archive.

    The problem happen because realpath will return the full path when the package no longer exist in disk.

    With this pull request the path will be relative and will work inside phar archive.

    opened by Ahed91 1
  • Merge config file in the service registration

    Merge config file in the service registration

    In this PR, I simply renamed the boot to register, and deleted boot as it is unused for now.

    mergeConfigFrom should be called in the register method, it means once the package being registered, its config are ready to use. Then other services can access them safely without caring about the order of application services bootstrap.

    This is also mentioned in the official documentation:

    To merge the configurations, use the mergeConfigFrom method within your service provider's register method.

    publishes is useful only in the console application, and in the console application all services will be booted, so it does not matter putting publishes whether in register or boot method. Some core services also put it in register to make code organized, such as MailServiceProvider::registerMarkdownRenderer.

    opened by ElfSundae 7
Releases(4.4.2)
Owner
Chris Fidao
Coding and servers. @UserScape-er. Breakfast tacos. Made @Servers-for-Hackers.
Chris Fidao
Laravel breeze is a PHP Laravel library that provides Authentication features such as Login page , Register, Reset Password and creating all Sessions Required.

About Laravel breeze To give you a head start building your new Laravel application, we are happy to offer authentication and application starter kits

null 3 Jul 30, 2022
Register for multiple Livestorm sessions from an external form. Practical use of Livestorm API with PHP/Javascript.

Livestorm Multi Session Registration Register for multiple Livestorm sessions from an external form. Practical use of Livestorm API with PHP/Javascrip

Nathan CHEVALIER 0 Dec 24, 2021
Source code behind the Laracasts Larabit: My Favorite Laravel Collections Methods

My Favorite Laravel Collections Methods This is the source code behind the Laracasts Larabit: My Favorite Laravel Collections Methods, and features al

Andrew Schmelyun 2 Dec 2, 2021
Source code behind the Laracasts Larabit: Using MySQL JSON Columns with Laravel

Using MySQL JSON Columns with Laravel This is the source code behind the Laracasts Larabit: Using MySQL JSON Columns with Laravel, and features all of

Andrew Schmelyun 2 Dec 24, 2021
Source code behind the Laracasts Larabit: Creating and Using Custom Blade Directives

This is the source code behind the Laracasts Larabit: Creating and Using Custom Blade Directives, and features all of the files and code available in that video.

Andrew Schmelyun 1 Nov 12, 2021
A lightweight package for handling API error responses.

Laravel API Errors This package provides an easy way to manage and handle error response for JSON API's. Installation You can install the package via

3 SIDED CUBE 2 Feb 9, 2022
This package provides new helper functions that take care of handling all the translation hassle and do it for you.

Laravel Translate Message ?? This package provides new helper functions that take care of handling all the translation hassle and do it for you. Insta

Basel Rabia 17 Feb 8, 2022
Load files and classes as lazy collections in Laravel.

Lody Load files and classes as lazy collections in Laravel. Installation composer require lorisleiva/lody Usage Lody enables you to fetch all exist

Loris Leiva 64 Dec 22, 2022
Automatically load your helpers in your laravel application.

Laravel AutoHelpers Automatically load your helpers in your laravel application. Installation You can install the package via composer: composer requi

Florian Wartner 6 Jul 26, 2021
Load Laravel service providers based on your application's environment.

Laravel EnvProviders A more finetuned way of managing your service providers in Laravel. This package allows you to configure the environment certain

Sven Luijten 79 Dec 29, 2022
Load head metadata from a manifest file which can be shared with a SPA project

Laravel Head Manifest Installation Step 1: Add Laravel Head Manifest to your laravel project composer require critiq/laravel-head-manifest Step 2: Add

Critiq 1 Nov 17, 2021
Load .env files for PHP.

PHP DotEnv Loader Simple library to load and get values from .env file(s). Install composer require murilo-perosa/dot-env How to Use Namespace use Mur

Murilo Perosa 1 Jan 15, 2022
With dadjokes every time you load your control panel you'll be greeted by an epic dad joke on the dashboard.

Filament Dad Jokes Widget With DadJokes every time you load your control panel you'll be greeted by an epic dad joke on the dashboard. Installation Yo

Craig Smith 15 Jan 7, 2023
A package for Myanmar Font, Phone and other Myanmar tools using Laravel Macro

Laravel Myanmar Tools A package for Myanmar Font, Phone and other Myanmar tools using Laravel Macro. Installation composer require pyaesoneaung/larave

Pyae Sone Aung 22 Dec 20, 2022
Laravel package for manage your URL redirects in database or other sources to get better SEO results

Laravel 8 and 9 package to manage URL redirections inside your Laravel application using different data sources. It allows a better SEO support for your Laravel site.

Siro Díaz Palazón 51 Sep 21, 2022
cybercog 996 Dec 28, 2022
A laravel Livewire Dynamic Selects with multiple selects depending on each other values, with infinite levels and totally configurable.

Livewire Combobox: A dynamic selects for Laravel Livewire A Laravel Livewire multiple selects depending on each other values, with infinite levels of

Damián Aguilar 25 Oct 30, 2022
A powerful form builder, for Laravel and other frameworks (stand-alone too)

Former A Laravelish way to create and format forms Former outputs form elements in HTML compatible with your favorite CSS framework (Bootstrap and Fou

null 1.3k Dec 22, 2022
Base library for repeated layout fields, content builders and other collection components

laravel-flexible-content This package's only purpose is to build custom repeated layout components, such as Laravel Nova's Flexible Content field or y

Whitecube 5 May 31, 2022