Laravel Trusted Proxies Wildcard: How to Configure TrustProxies Middleware Correctly

Setting TrustProxies to trust all proxies (*) lets attackers spoof IP addresses and bypass rate limiting, IP-based access controls, and audit logging.

Medium severity Infrastructure Security Updated 2026-05-01 Markdown

Web applications deployed behind load balancers, CDNs, or reverse proxies face a common problem: the TCP connection reaching the PHP application comes from the proxy, not the end user. The client's real IP address, the original protocol (HTTP vs HTTPS), and the original hostname are passed in HTTP headers like X-Forwarded-For, X-Forwarded-Proto, and X-Forwarded-Host. Laravel's TrustProxies middleware reads these headers to present the correct client information to the application.

When the trusted proxies list is set to * (wildcard), Laravel trusts these forwarded headers from any source — not just the actual load balancer. An attacker connecting directly to the application server can send X-Forwarded-For: 127.0.0.1 and appear as localhost. This bypasses IP-based rate limiting (which checks $request->ip()), IP allowlists for admin areas, audit logging that records client IPs, and any geographic restriction based on IP address.

This misconfiguration is extremely common because tutorials and quick-start guides often recommend * as the simple solution to make $request->ip() work correctly behind a load balancer. Many developers set it and forget it, not realizing they are trusting every client on the internet to self-report their own IP address. The correct solution requires knowing the actual IP ranges of your proxies — information available from your hosting provider and CDN documentation.

The Problem

Laravel's TrustProxies middleware reads headers like X-Forwarded-For and X-Forwarded-Proto to determine the real client IP and protocol when behind a load balancer. Setting the trusted proxies to * (wildcard) means your application trusts these headers from any source — including attackers. This allows IP spoofing: an attacker can send X-Forwarded-For: 127.0.0.1 to bypass IP-based rate limiting, access controls, and audit logging.

How to Fix

  1. 1

    Identify your actual proxy IP addresses

    Determine the IP addresses of your load balancers and reverse proxies:

    # AWS ALB/ELB — use CIDR ranges
    # Check: https://ip-ranges.amazonaws.com/ip-ranges.json
    # Cloudflare — published IP ranges
    # Check: https://www.cloudflare.com/ips/
    # Single reverse proxy (Nginx on same server)
    # Usually 127.0.0.1
    # Laravel Forge with Nginx
    # Usually 127.0.0.1
  2. 2

    Configure specific proxy IPs in the middleware

    In app/Http/Middleware/TrustProxies.php (Laravel 10) or bootstrap/app.php (Laravel 11+):

    // Laravel 11+ in bootstrap/app.php
    ->withMiddleware(function (Middleware $middleware) {
        $middleware->trustProxies(
            at: ['192.168.1.1', '10.0.0.0/8'],
            headers: Request::HEADER_X_FORWARDED_FOR |
                     Request::HEADER_X_FORWARDED_HOST |
                     Request::HEADER_X_FORWARDED_PORT |
                     Request::HEADER_X_FORWARDED_PROTO
        );
    })
    // Laravel 10 in app/Http/Middleware/TrustProxies.php
    protected $proxies = ['192.168.1.1', '10.0.0.0/8'];
    For cloud platforms where proxy IPs change, use the specific platform approach rather than *.
  3. 3

    Handle dynamic proxy IPs on cloud platforms

    On platforms like AWS or Google Cloud where proxy IPs rotate:

    // Laravel Vapor — automatically configured, no changes needed
    // AWS with ALB — trust the VPC CIDR
    protected $proxies = ['10.0.0.0/8', '172.16.0.0/12'];
    // Cloudflare — use the fideloper/proxy package or list their IPs
    protected $proxies = [
        '173.245.48.0/20', '103.21.244.0/22', '103.22.200.0/22',
        '103.31.4.0/22', '141.101.64.0/18', '108.162.192.0/18',
        '190.93.240.0/20', '188.114.96.0/20', '197.234.240.0/22',
        '198.41.128.0/17', '162.158.0.0/15', '104.16.0.0/13',
        '104.24.0.0/14', '172.64.0.0/13', '131.0.72.0/22',
    ];

    Keep these ranges updated as providers add new IPs.

How to Verify

Test IP spoofing:

curl -H 'X-Forwarded-For: 1.2.3.4' https://yourapp.com/api/me

The returned IP should be your actual IP, not 1.2.3.4, unless the request came through your actual proxy. Run php artisan stackshield:scan --check=SS045 to verify.

Prevention

Never use * for trusted proxies in production. Document your infrastructure proxy IPs. Update proxy IP lists when changing cloud providers or CDN configurations. Use StackShield to monitor for wildcard proxy configurations.

Frequently Asked Questions

What if I don't know my proxy IPs?

Check your hosting provider documentation. For Laravel Forge: 127.0.0.1. For AWS ALB: your VPC CIDR range. For Cloudflare: their published IP list. You can also check access logs to see which IPs are connecting to your application.

Is trusting all proxies safe behind Cloudflare?

No. Even behind Cloudflare, attackers can bypass CDN and connect directly to your origin server if they discover its IP. In that case, trusting * means they can spoof headers. Always restrict to Cloudflare's published IP ranges.

Does the trusted proxies configuration affect $request->ip() in Laravel?

Yes, that is precisely what it controls. When a request comes through a proxy, $request->ip() reads the IP from the X-Forwarded-For header if the source is trusted. Without correct trusted proxy configuration, $request->ip() returns either the proxy's IP (breaking rate limiting) or the spoofed IP from the header (creating a security bypass). Correct configuration is required for both security and functionality.

What headers does Laravel read from trusted proxies?

By default, Laravel reads X-Forwarded-For (client IP), X-Forwarded-Host (original hostname), X-Forwarded-Port (original port), and X-Forwarded-Proto (HTTP or HTTPS). In Laravel 11, configure which headers to trust via the headers parameter in trustProxies(). Only enable headers your actual proxy sends — trusting headers your proxy does not set allows attacker manipulation of those values.

How do I verify that IP-based rate limiting is working correctly behind my proxy?

Make a request from your IP, hit the rate limit, then retry with X-Forwarded-For: 9.9.9.9 in the header. If you are not rate limited with the spoofed IP, your proxy configuration is misconfigured and attackers can bypass rate limiting by faking their IP. The spoofed header should have no effect when trusted proxies are configured correctly with specific IP addresses.

Related Security Terms

Free security check

Is your Laravel app exposed right now?

34% of Laravel apps we scan have at least one critical issue. Most teams don't find out until something breaks. Our free scan checks your live application in under 60 seconds.

18% have debug mode on
72% missing security headers
12% have exposed .env
Scan My App Free No signup required. Results in 60 seconds.