diff options
author | dizzy <diosmosis@users.noreply.github.com> | 2021-07-16 06:02:36 +0300 |
---|---|---|
committer | GitHub <noreply@github.com> | 2021-07-16 06:02:36 +0300 |
commit | dc29fc3e39e3696b7c3f188f23d3fe415afa42bd (patch) | |
tree | d9b565765c55dc4541cfd78d6112fc979ed042f6 /core | |
parent | 5b9076d7535142365be6a5789a6395aa03b3bd13 (diff) |
add config to read the last IP address in the list of proxies rather than the first (#17765)
* by default read the last IP address in the list of proxies rather than the first
* apply review feedback
* apply review feedback
* update expected screenshot
Diffstat (limited to 'core')
-rw-r--r-- | core/IP.php | 50 |
1 files changed, 37 insertions, 13 deletions
diff --git a/core/IP.php b/core/IP.php index efa2226627..28b640e7d3 100644 --- a/core/IP.php +++ b/core/IP.php @@ -80,13 +80,19 @@ class IP $proxyIps[] = $default; + $shouldReadLastProxyIp = Config::getInstance()->General['proxy_ip_read_last_in_list'] == 1; + // examine proxy headers foreach ($proxyHeaders as $proxyHeader) { if (!empty($_SERVER[$proxyHeader])) { // this may be buggy if someone has proxy IPs and proxy host headers configured as // `$_SERVER[$proxyHeader]` could be eg $_SERVER['HTTP_X_FORWARDED_HOST'] and // include an actual host name, not an IP - $proxyIp = self::getFirstIpFromList($_SERVER[$proxyHeader], $proxyIps); + if ($shouldReadLastProxyIp) { + $proxyIp = self::getLastIpFromList($_SERVER[$proxyHeader], $proxyIps); + } else { + $proxyIp = self::getFirstIpFromList($_SERVER[$proxyHeader], $proxyIps); + } if (strlen($proxyIp) && stripos($proxyIp, 'unknown') === false) { return $proxyIp; } @@ -107,20 +113,38 @@ class IP { $p = strrpos($csv, ','); if ($p !== false) { - $elements = explode(',', $csv); - foreach ($elements as $ipString) { - $element = trim(Common::sanitizeInputValue($ipString)); - if(empty($element)) { - continue; - } - $ip = \Matomo\Network\IP::fromStringIP(IPUtils::sanitizeIp($element)); - if (empty($excludedIps) || (!in_array($element, $excludedIps) && !$ip->isInRanges($excludedIps))) { - return $element; - } - } + $elements = self::getIpsFromList($csv, $excludedIps); + return reset($elements) ?: ''; + } + return trim(Common::sanitizeInputValue($csv)); + } - return ''; + public static function getLastIpFromList($csv, $excludedIps = null) + { + $p = strrpos($csv, ','); + if ($p !== false) { + $elements = self::getIpsFromList($csv, $excludedIps); + return end($elements) ?: ''; } return trim(Common::sanitizeInputValue($csv)); } + + private static function getIpsFromList(string $csv, ?array $excludedIps) + { + $result = []; + + $elements = explode(',', $csv); + foreach ($elements as $ipString) { + $element = trim(Common::sanitizeInputValue($ipString)); + if(empty($element)) { + continue; + } + $ip = \Matomo\Network\IP::fromStringIP(IPUtils::sanitizeIp($element)); + if (empty($excludedIps) || (!in_array($element, $excludedIps) && !$ip->isInRanges($excludedIps))) { + $result[] = $element; + } + } + + return $result; + } } |