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.
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.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With