Laravel Version
12.63.0, 13.x
PHP Version
8.4
Database Driver & Version
No response
Description
I have an application running on ELB behind a CloudFront distribution. Both ELB and CloudFront forward the request downstream resulting in my X-Forwarded-For header looking like this:
1.1.1.1, 2.2.2.2
Where 1.1.1.1 is my actual client IP address, 2.2.2.2 is CloudFront, and 3.3.3.3 is ELB.
I have trusted all proxies with the line:
$middleware->trustProxies(
at: '*',
headers: Request::HEADER_X_FORWARDED_FOR |
Request::HEADER_X_FORWARDED_HOST |
Request::HEADER_X_FORWARDED_PORT |
Request::HEADER_X_FORWARDED_PROTO |
Request::HEADER_X_FORWARDED_AWS_ELB
);
However when I call $request->ip() I get 2.2.2.2
I've dug into this a bit and discovered this is because when Laravel trusts all proxies, it sets the list of trusted IPs to the REMOTE_ADDR (3.3.3.3 in my case).
This list ends up getting passed to Symfony, which then returns the latest untrusted IP in the list, which is 2.2.2.2.
As Symfony does not support wildcards, my proposed fix for this is to gather a list of all X-FORWARDED-FOR and FORWARDED IP addresses, and set them into the $trustedProxies array, so that Symfony trusts the entire chain and will therefore return the first trusted IP, 1.1.1.1 in my case.
I note that there is a test case for this but it appears to be incorrect, according to https://developer.mozilla.org/en-US/docs/Web/HTTP/Reference/Headers/X-Forwarded-For the leftmost IP is the original client IP, which reflects in what I am seeing.
I have a fix in progress for this, will raise a PR
Steps To Reproduce
- Start a Laravel app with TrustProxies:*
- Craft a request with multiple IP addresses in X-FORWARDED-FOR or FORWARDED header
- Observe that the last IP in the list is used as the original client IP, not the first!
Laravel Version
12.63.0, 13.x
PHP Version
8.4
Database Driver & Version
No response
Description
I have an application running on ELB behind a CloudFront distribution. Both ELB and CloudFront forward the request downstream resulting in my X-Forwarded-For header looking like this:
1.1.1.1, 2.2.2.2Where
1.1.1.1is my actual client IP address, 2.2.2.2 is CloudFront, and 3.3.3.3 is ELB.I have trusted all proxies with the line:
However when I call
$request->ip()I get2.2.2.2I've dug into this a bit and discovered this is because when Laravel trusts all proxies, it sets the list of trusted IPs to the REMOTE_ADDR (3.3.3.3 in my case).
This list ends up getting passed to Symfony, which then returns the latest untrusted IP in the list, which is
2.2.2.2.As Symfony does not support wildcards, my proposed fix for this is to gather a list of all X-FORWARDED-FOR and FORWARDED IP addresses, and set them into the $trustedProxies array, so that Symfony trusts the entire chain and will therefore return the first trusted IP, 1.1.1.1 in my case.
I note that there is a test case for this but it appears to be incorrect, according to https://developer.mozilla.org/en-US/docs/Web/HTTP/Reference/Headers/X-Forwarded-For the leftmost IP is the original client IP, which reflects in what I am seeing.
I have a fix in progress for this, will raise a PR
Steps To Reproduce