View Issue Details

IDProjectCategoryView StatusLast Update
0005130OXID eShop (all versions)4.02. Session handlingpublic2017-05-02 13:47
Reporterd3 
PrioritynormalSeverityminorReproducibilityalways
Status acknowledgedResolutionopen 
Product Version4.6.7 
Target VersionFixed in Version 
Summary0005130: no check of the user ip adress
DescriptionIn 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"
 
TagsNo tags attached.
ThemeNot defined
BrowserAll
PHP VersionNot defined
MySQL VersionNot defined

Activities

d3

2013-08-02 10:32

reporter   ~0008942

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\[email protected]";

        return preg_match($sPattern, $sHost);
    }

    /**
     * @param string $sHost
     * @return int
     */
    public function d3isIPNumList($sHost)
    {
        $sSP = "\d{1,3}";
        $sIPPattern = "@$sSP\.$sSP\.$sSP\[email protected]";
        $sPattern = "@(".$sIPPattern.")(,\s*".$sIPPattern.")*@";

        return preg_match($sPattern, $sHost);
    }

FibreFoX

2013-08-02 10:54

reporter   ~0008944

The given solution lacks support for IPv6

d3

2017-04-25 11:16

reporter   ~0012047

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

d3

2017-04-25 11:56

reporter   ~0012048

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