Welcome Guest, Not a member yet? Register   Sign In
$this->input->ip_address() security question
#1

[eluser]Unknown[/eluser]
Hello, all:
We ran into a problem this morning, and I see a way to fix it, but it involves changing a core function and I assume that there's a reason it's the way it is now.

Here's what happened, as far as we can tell: Our hosting company started using reverse proxy servers to serve our account, which resulted in $_SERVER['REMOTE_ADDR'] no longer being an accurate or stable representation of the user's ip. From inspection of server variables, $_SERVER['HTTP_X_FORWARDED_FOR'] appears to be reliable. $_SERVER['HTTP_CLIENT_IP'] isn't defined, if you're wondering. But the input->ip_address() function doesn't use HTTP_X_FORWARDED_FOR unless a) REMOTE_ADDR is on a predefined proxy_ips whitelist, or b) neither REMOTE_ADDR nor HTTP_CLIENT_IP is defined. Since we didn't know this was coming, we don't have a whitelist of proxy servers. Since our hosting company's tech support is ill-informed, they weren't able to help with that either.

So, unless we can get a good proxy whitelist, the only way I see to fix it is to alter the order of the if statements in system/core/input.php so that HTTP_X_FORWARDED_FOR takes priority over REMOTE_ADDR when both are defined. I can certainly do that, but I don't want to monkey around with that until and unless I fully understand the implications.

So, what is the thinking behind the order of the if statements in input->ip_address()? Is HTTP_X_FORWARDED_FOR more vulnerable to spoofing than REMOTE_ADDR?

Thanks in advance,
--Jacob

Below I'm pasting the code from my copy of ip_address() in case you want to follow along.
Code:
/**
    * Fetch the IP Address
    *
    * @access    public
    * @return    string
    */
    function ip_address()
    {
        if ($this->ip_address !== FALSE)
        {
            return $this->ip_address;
        }

        if (config_item('proxy_ips') != '' && $this->server('HTTP_X_FORWARDED_FOR') && $this->server('REMOTE_ADDR'))
        {
            $proxies = preg_split('/[\s,]/', config_item('proxy_ips'), -1, PREG_SPLIT_NO_EMPTY);
            $proxies = is_array($proxies) ? $proxies : array($proxies);

            $this->ip_address = in_array($_SERVER['REMOTE_ADDR'], $proxies) ? $_SERVER['HTTP_X_FORWARDED_FOR'] : $_SERVER['REMOTE_ADDR'];
        }
        elseif ($this->server('REMOTE_ADDR') AND $this->server('HTTP_CLIENT_IP'))
        {
            $this->ip_address = $_SERVER['HTTP_CLIENT_IP'];
        }
        elseif ($this->server('REMOTE_ADDR'))
        {
            $this->ip_address = $_SERVER['REMOTE_ADDR'];
        }
        elseif ($this->server('HTTP_CLIENT_IP'))
        {
            $this->ip_address = $_SERVER['HTTP_CLIENT_IP'];
        }
        elseif ($this->server('HTTP_X_FORWARDED_FOR'))
        {
            $this->ip_address = $_SERVER['HTTP_X_FORWARDED_FOR'];
        }

        if ($this->ip_address === FALSE)
        {
            $this->ip_address = '0.0.0.0';
            return $this->ip_address;
        }

        if (strpos($this->ip_address, ',') !== FALSE)
        {
            $x = explode(',', $this->ip_address);
            $this->ip_address = trim(end($x));
        }

        if ( ! $this->valid_ip($this->ip_address))
        {
            $this->ip_address = '0.0.0.0';
        }

        return $this->ip_address;
    }




Theme © iAndrew 2016 - Forum software by © MyBB