Permalink
Browse files

adding proper support for cases where a proxy server passes multiple …

…ip addresses. fixing #356
  • Loading branch information...
Peter Adams
Peter Adams committed Aug 26, 2018
1 parent 5ed4416 commit e69998c5b36539d9d2cbc0f9bfb0ca436c28573f
Showing with 94 additions and 6 deletions.
  1. +49 −6 modules/base/classes/trackingEventHelpers.php
  2. +45 −0 owa_lib.php
@@ -238,13 +238,56 @@ static function languageDefault() {
static function ipAddressDefault() {
if ( owa_coreAPI::getServerParam( 'HTTP_X_FORWARDED_FOR' ) ) {
$ip = '';
$ip = owa_coreAPI::getServerParam( 'HTTP_X_FORWARDED_FOR' );
} else {
$ip = owa_coreAPI::getServerParam('REMOTE_ADDR');
// array of SERVER params that could possibly contain the IP address
// ordered by probability of relevant match
$possible_ip_params = array(
'HTTP_CLIENT_IP',
'HTTP_X_FORWARDED_FOR',
'HTTP_X_CLUSTER_CLIENT_IP',
'HTTP_FORWARDED_FOR',
'REMOTE_ADDR'
);
// check for IP address, break when found.
foreach ( $possible_ip_params as $param ) {
if ( owa_coreAPI::getServerParam( $param ) ) {
$ip = owa_coreAPI::getServerParam( $param );
owa_coreAPI::debug("ip address found in $param");
break;
}
}
// check to see if there are multiple ips possibly passed from a poxy
if ( strpos( $ip, ',' ) ) {
owa_coreAPI::debug('multiple ip addresses found');
// evaluate each IP to make sure it's valid and that it's not a private IP
$candidate_ips = explode( ',', $ip );
foreach ( $candidate_ips as $candidate_ip ) {
$candidate_ip = trim( $candidate_ip );
if ( owa_lib::isValidIp( $candidate_ip ) && ! owa_lib::isPrivateIp( $candidate_ip ) ) {
$ip = $candidate_ip;
break;
}
}
// if still no valid public IP then just use the first one found
if ( strpos( $ip, ',' ) ) {
$ip = trim( $candidate_ips[0] ) ;
}
}
// Anonymize IP if needed.
@@ -1320,6 +1320,51 @@ public static function moveFile( $oldfile, $newfile ) {
}
}
}
public static function isValidIp( $ip_address ) {
// if valid ip address
if ( ! empty( $ip_address )
&& ip2long( $ip_address ) != -1
&& ip2long( $ip_address ) != false
) {
return true;
}
}
// check to see if the IP address falls within known private IP ranges
public static function isPrivateIp( $ip_address ) {
$ip = ip2long( $ip_address);
$private_ip_ranges = array (
array('0.0.0.0','2.255.255.255'),
array('10.0.0.0','10.255.255.255'),
array('127.0.0.0','127.255.255.255'),
array('169.254.0.0','169.254.255.255'),
array('172.16.0.0','172.31.255.255'),
array('192.0.2.0','192.0.2.255'),
array('192.168.0.0','192.168.255.255'),
array('255.255.255.0','255.255.255.255')
);
//check to see if it falls within a known private range
foreach ( $private_ip_ranges as $range ) {
$min = ip2long( $range[0] );
$max = ip2long( $range[1] );
if ( ( $ip >= $min ) && ( $ip <= $max ) ) {
return true;
}
}
// if it makes it through the checks then it's not private.
return false;
}
}
?>

1 comment on commit e69998c

@wimbley

This comment has been minimized.

wimbley commented on e69998c Aug 26, 2018

Now I see Country & City on an entry - THANK YOU!!! Am I correct in that all datas collected until now will be bad but it will work from here on out?

Please sign in to comment.