Thanks for the report. Wordfence takes addresses starting on the left because we want the address closest to the visitor, rather than closest to you which may be one of your proxies. You've clearly identified a flaw in this algorithm, so I've changed it to grab addresses from the left but skip private addresses. I've also improved our algorithm which determines what a private address is. We now consider the following ranges to be private:
private static $privateAddrs = array(
('0.0.0.0/8',0,16777215),
('10.0.0.0/8',167772160,184549375),
('100.64.0.0/10',1681915904,1686110207),
('127.0.0.0/8',2130706432,2147483647),
('169.254.0.0/16',2851995648,2852061183),
('172.16.0.0/12',2886729728,2887778303),
('192.0.0.0/29',3221225472,3221225479),
('192.0.2.0/24',3221225984,3221226239),
('192.88.99.0/24',3227017984,3227018239),
('192.168.0.0/16',3232235520,3232301055),
('198.18.0.0/15',3323068416,3323199487),
('198.51.100.0/24',3325256704,3325256959),
('203.0.113.0/24',3405803776,3405804031),
('224.0.0.0/4',3758096384,4026531839),
('240.0.0.0/4',4026531840,4294967295),
('255.255.255.255/32',4294967295,4294967295)
The first element of each array is the CIDR version of an address, the next two are the integer lowest and highest addresses in the ranges that we use for the calculation.
The new function is:
public static function isPrivateAddress($addr){
$num = self::inet_aton($addr);
foreach(self::$privateAddrs as $a){
if($num >= $a[1] && $num <= $a[2]){
return true;
}
}
return false;
}
This will go out with the next release.
Regards,
Mark
PS: If you found this helpful, please rate Wordfence 5 stars.
http://wordpress.org/plugins/wordfence/