bug #16736 [Request] Ignore invalid IP addresses sent by proxies (GromNaN)
This PR was submitted for the 2.8 branch but it was merged into the 2.3 branch instead (closes #16736).
Discussion
----------
[Request] Ignore invalid IP addresses sent by proxies
| Q | A
| ------------- | ---
| Bug fix? | yes
| New feature? | no
| BC breaks? | ?
| Deprecations? | no
| Tests pass? | yes
| Fixed tickets | #15525
| License | MIT
| Doc PR | n/a
The [RFC 7239](https://tools.ietf.org/html/rfc7239#section-6.2) allows other values that IP addresses to be passed in `Forwarded`header and [Nginx can add `unknown` to the `X-Forwarded-For`header](http://www.squid-cache.org/Doc/config/forwarded_for/).
To prevent these invalid IP addresses from being returned as "Client IP", this PR ensure that they are excluded.
Commits
-------
6578806
[Request] Ignore invalid IP addresses sent by proxies
This commit is contained in:
commit
50b48f6516
@ -769,8 +769,7 @@ class Request
|
|||||||
|
|
||||||
$clientIps = array_map('trim', explode(',', $this->headers->get(self::$trustedHeaders[self::HEADER_CLIENT_IP])));
|
$clientIps = array_map('trim', explode(',', $this->headers->get(self::$trustedHeaders[self::HEADER_CLIENT_IP])));
|
||||||
$clientIps[] = $ip; // Complete the IP chain with the IP the request actually came from
|
$clientIps[] = $ip; // Complete the IP chain with the IP the request actually came from
|
||||||
|
$firstTrustedIp = null;
|
||||||
$ip = $clientIps[0]; // Fallback to this when the client IP falls into the range of trusted proxies
|
|
||||||
|
|
||||||
// Eliminate all IPs from the forwarded IP chain which are trusted proxies
|
// Eliminate all IPs from the forwarded IP chain which are trusted proxies
|
||||||
foreach ($clientIps as $key => $clientIp) {
|
foreach ($clientIps as $key => $clientIp) {
|
||||||
@ -779,13 +778,22 @@ class Request
|
|||||||
$clientIps[$key] = $clientIp = $match[1];
|
$clientIps[$key] = $clientIp = $match[1];
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (!filter_var($clientIp, FILTER_VALIDATE_IP)) {
|
||||||
|
unset($clientIps[$key]);
|
||||||
|
}
|
||||||
|
|
||||||
if (IpUtils::checkIp($clientIp, self::$trustedProxies)) {
|
if (IpUtils::checkIp($clientIp, self::$trustedProxies)) {
|
||||||
unset($clientIps[$key]);
|
unset($clientIps[$key]);
|
||||||
|
|
||||||
|
// Fallback to this when the client IP falls into the range of trusted proxies
|
||||||
|
if (null === $firstTrustedIp) {
|
||||||
|
$firstTrustedIp = $clientIp;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// Now the IP chain contains only untrusted proxies and the client IP
|
// Now the IP chain contains only untrusted proxies and the client IP
|
||||||
return $clientIps ? array_reverse($clientIps) : array($ip);
|
return $clientIps ? array_reverse($clientIps) : array($firstTrustedIp);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -863,6 +863,9 @@ class RequestTest extends \PHPUnit_Framework_TestCase
|
|||||||
|
|
||||||
// client IP with port
|
// client IP with port
|
||||||
array(array('88.88.88.88'), '127.0.0.1', '88.88.88.88:12345, 127.0.0.1', array('127.0.0.1')),
|
array(array('88.88.88.88'), '127.0.0.1', '88.88.88.88:12345, 127.0.0.1', array('127.0.0.1')),
|
||||||
|
|
||||||
|
// invalid forwarded IP is ignored
|
||||||
|
array(array('88.88.88.88'), '127.0.0.1', 'unknown,88.88.88.88', array('127.0.0.1')),
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Reference in New Issue
Block a user