Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Getting IPAddress via a proxy with PHP?

Tags:

php

ip-address

I run security checks on a number of AJAX calls to see if the same IP requested that I have on record.

I used the following set of class functions to establish the IP (which can come via load balancers, hence the lengthly methodology.

    private function IPMask_Match ($network, $ip) {
      $ip_arr = explode('/', $network);
      if (count($ip_arr) < 2) {
        $ip_arr = array($ip_arr[0], null);
      }
      $network_long = ip2long($ip_arr[0]);
      $x = ip2long($ip_arr[1]);
      $mask =  long2ip($x) == $ip_arr[1] ? $x : 0xffffffff << (32 - $ip_arr[1]);
      $ip_long = ip2long($ip);
      return ($ip_long & $mask) == ($network_long & $mask);
    }


    private function IPCheck_RFC1918 ($IP) {
      $PrivateIP = false;
      if (!$PrivateIP) {
        $PrivateIP = $this->IPMask_Match('127.0.0.0/8', $IP);
      }
      if (!$PrivateIP) {
        $PrivateIP = $this->IPMask_Match('10.0.0.0/8', $IP);
      }
      if (!$PrivateIP) {
        $PrivateIP = $this->IPMask_Match('172.16.0.0/12', $IP);
      }
      if (!$PrivateIP) {
        $PrivateIP = $this->IPMask_Match('192.168.0.0/16', $IP);
      }
      return $PrivateIP;
    }


    public function getIP () {
      $UsesProxy = (!empty($_SERVER['HTTP_X_FORWARDED_FOR']) || !empty($_SERVER['HTTP_CLIENT_IP'])) ? true : false;
      if ($UsesProxy && !empty($_SERVER['HTTP_CLIENT_IP'])) {
        $UserIP = $_SERVER['HTTP_CLIENT_IP'];
      }
      elseif ($UsesProxy && !empty($_SERVER['HTTP_X_FORWARDED_FOR'])) {
        $UserIP = $_SERVER['HTTP_X_FORWARDED_FOR'];
        if (strstr($UserIP, ',')) {
          $UserIPArray = explode(',', $UserIP);
          foreach ($UserIPArray as $IPtoCheck) {
            if (!$this->IPCheck_RFC1918($IPtoCheck)) {
              $UserIP = $IPtoCheck;
              break;
            }
          }
          if ($UserIP == $_SERVER['HTTP_X_FORWARDED_FOR']) {
            $UserIP = $_SERVER['REMOTE_ADDR'];
          }
        }
      }
      else{
        $UserIP = $_SERVER['REMOTE_ADDR'];
      }
      return $UserIP;
    }

The Problem is I've been getting problems with users operating via a proxy. Can anyone indicate why that might be? I've used basic free proxy's online to try and emulate, but it doesn't look to be getting variable IPs or anything - so I'm not sure why this would be saying the two IPs don't match.

like image 943
waxical Avatar asked Oct 19 '12 09:10

waxical


1 Answers

I am going to explain what a proxy is first so we are both on the same page.

What Is A Proxy

A proxy is usually a single computer that accesses the internet ON BEHALF OF the user and then the proxy sends the results back to the user. The problem appears when there could be hundreds or even thousands of other people also using that one computer - and they all have the SAME IP address but normally the headers indicate that the users are via a proxy.

Your script i am assuming (without properly looking) is getting the IP's and headers mixed up.

Different Solution

There is a better way. Use sessions and save a key in the session ensuring they have previously been to the main site first BEFORE accessing the ajax page. Example:

index.php

session_start();
$_SESSION['ajax_ok'] = true;

ajax/username_check.php

session_start();
if (empty($_SESSION['ajax_ok'])) {
    die("You can not access this page...");
}

That will enforce that they must visit your main site first and the client must also support sessions which most browsers will which is a plus to help prevent bots etc abusing your ajax scripts.

More reliable and easier solution than using that mangle of code you got above ><

What if you can't use sessions?

If you can't use sessions on the specific comp you're on, you could setup another computer, rewrite the session handler (using the callbacks that php provides) or instead of using the file system use something else like the database for sessions instead? There must be something your website uses that the sessions could also use. Such as if you have a load balancer file based sessions generally wont work anyway so it's generally a good idea to change the sessions to use something else like i mentioned above.

like image 88
HenchHacker Avatar answered Sep 21 '22 15:09

HenchHacker