View Issue Details
ID | Project | Category | View Status | Date Submitted | Last Update |
---|---|---|---|---|---|
0005130 | OXID eShop (all versions) | 4.02. Session handling | public | 2013-05-28 16:27 | 2023-11-20 12:10 |
Reporter | d3 | Assigned To | |||
Priority | normal | Severity | feature | Reproducibility | always |
Status | confirmed | Resolution | open | ||
Product Version | 4.6.7 | ||||
Summary | 0005130: no check of the user ip adress | ||||
Description | In some cases oxutilsserver::getRemoteAdress() don't return the correct IP adress, but a string like "unkown". we take a log of the $_SERVER variable for the case: [HTTP_X_FORWARDED_FOR] => unknown [HTTP_CACHE_CONTROL] => max-age=0 [HTTP_CONNECTION] => close [SERVER_SIGNATURE] => [SERVER_SOFTWARE] => Apache [SERVER_NAME] => xxxx [SERVER_ADDR] => 77.75.249.72 [SERVER_PORT] => 80 [REMOTE_HOST] => xxxxx [REMOTE_ADDR] => 46.237.193.154 getRemoteAddress() checks only isset($_SERVER["HTTP_X_FORWARDED_FOR"]) and return it as UserIP-adress without any syntax check. In this case, the correct return was "REMOTE_ADDR" | ||||
Tags | No tags attached. | ||||
Theme | Not defined | ||||
Browser | All | ||||
PHP Version | Not defined | ||||
Database Version | Not defined | ||||
|
a possible solution: public function getRemoteAddress() { if ( isset( $_SERVER["HTTP_X_FORWARDED_FOR"] ) && $this->d3isIPNumList($_SERVER["HTTP_X_FORWARDED_FOR"])) { $sIP = $_SERVER["HTTP_X_FORWARDED_FOR"]; $sIP = preg_replace('/,.*$/', '', $sIP); } elseif ( isset( $_SERVER["HTTP_CLIENT_IP"] ) && $this->d3isIPNum($_SERVER["HTTP_CLIENT_IP"]) ) { $sIP = $_SERVER["HTTP_CLIENT_IP"]; } else { $sIP = $_SERVER["REMOTE_ADDR"]; } return $sIP; } /** * @param string $sHost * @return int */ public function d3isIPNum($sHost) { $sSP = "\d{1,3}"; $sPattern = "@$sSP\.$sSP\.$sSP\.$sSP@"; return preg_match($sPattern, $sHost); } /** * @param string $sHost * @return int */ public function d3isIPNumList($sHost) { $sSP = "\d{1,3}"; $sIPPattern = "@$sSP\.$sSP\.$sSP\.$sSP@"; $sPattern = "@(".$sIPPattern.")(,\s*".$sIPPattern.")*@"; return preg_match($sPattern, $sHost); } |
|
The given solution lacks support for IPv6 |
|
How about: public function getRemoteAddress() { if ( isset( $_SERVER["HTTP_X_FORWARDED_FOR"] ) && filter_var($_SERVER["HTTP_X_FORWARDED_FOR"], FILTER_VALIDATE_IP)) { $sIP = $_SERVER["HTTP_X_FORWARDED_FOR"]; $sIP = preg_replace('/,.*$/', '', $sIP); } elseif ( isset( $_SERVER["HTTP_CLIENT_IP"] ) && filter_var($_SERVER["HTTP_X_FORWARDED_FOR"], FILTER_VALIDATE_IP) ) { $sIP = $_SERVER["HTTP_CLIENT_IP"]; } else { $sIP = $_SERVER["REMOTE_ADDR"]; } return $sIP; } source: http://php.net/manual/de/filter.filters.validate.php#FILTER_VALIDATE_IP http://php.net/manual/de/function.filter-var.php KH |
|
An implementation like Symfony did it (http://api.symfony.com/3.1/Symfony/Component/HttpFoundation/Request.html#method_getClientIp), would be the best way. RE |
|
@d3 It seems that the original issue was caused by an invalid implementation of squid I will handle this as a feature request to consider when we improve our IP and Domain handling (including IPv6 checks) |