tag:blogger.com,1999:blog-865923359735383241.post5175864184902712432..comments2023-10-29T07:27:09.012-06:00Comments on Ccna final exam - java, php, javascript, ios, cshap all in one: What is the most accurate way to retrieve a user"s correct IP address in PHP?Unknownnoreply@blogger.comBlogger8125tag:blogger.com,1999:blog-865923359735383241.post-83511950181789155782012-06-08T19:32:51.415-06:002012-06-08T19:32:51.415-06:00/**
* Sanitizes IPv4 address according to Ilia Al.../**<br /> * Sanitizes IPv4 address according to Ilia Alshanetsky's book<br /> * "php|architect?s Guide to PHP Security", chapter 2, page 67.<br /> *<br /> * @param string $ip An IPv4 address<br /> */<br />public static function sanitizeIpAddress($ip = '')<br />{<br />if ($ip == '')<br /> {<br /> $rtnStr = '0.0.0.0';<br /> }<br />else<br /> {<br /> $rtnStr = long2ip(ip2long($ip));<br /> }<br /><br />return $rtnStr;<br />}<br /><br />//---------------------------------------------------<br /><br />/**<br /> * Returns the sanitized HTTP_X_FORWARDED_FOR server variable.<br /> *<br /> */<br />public static function getXForwardedFor()<br />{<br />if (isset($_SERVER['HTTP_X_FORWARDED_FOR']))<br /> {<br /> $rtnStr = $_SERVER['HTTP_X_FORWARDED_FOR'];<br /> }<br />elseif (isset($HTTP_SERVER_VARS['HTTP_X_FORWARDED_FOR']))<br /> {<br /> $rtnStr = $HTTP_SERVER_VARS['HTTP_X_FORWARDED_FOR'];<br /> }<br />elseif (getenv('HTTP_X_FORWARDED_FOR'))<br /> {<br /> $rtnStr = getenv('HTTP_X_FORWARDED_FOR');<br /> }<br />else<br /> {<br /> $rtnStr = '';<br /> }<br /><br />// Sanitize IPv4 address (Ilia Alshanetsky):<br />if ($rtnStr != '')<br /> {<br /> $rtnStr = explode(', ', $rtnStr);<br /> $rtnStr = self::sanitizeIpAddress($rtnStr[0]);<br /> }<br /><br />return $rtnStr;<br />}<br /><br />//---------------------------------------------------<br /><br />/**<br /> * Returns the sanitized REMOTE_ADDR server variable.<br /> *<br /> */<br />public static function getRemoteAddr()<br />{<br />if (isset($_SERVER['REMOTE_ADDR']))<br /> {<br /> $rtnStr = $_SERVER['REMOTE_ADDR'];<br /> }<br />elseif (isset($HTTP_SERVER_VARS['REMOTE_ADDR']))<br /> {<br /> $rtnStr = $HTTP_SERVER_VARS['REMOTE_ADDR'];<br /> }<br />elseif (getenv('REMOTE_ADDR'))<br /> {<br /> $rtnStr = getenv('REMOTE_ADDR');<br /> }<br />else<br /> {<br /> $rtnStr = '';<br /> }<br /><br />// Sanitize IPv4 address (Ilia Alshanetsky):<br />if ($rtnStr != '')<br /> {<br /> $rtnStr = explode(', ', $rtnStr);<br /> $rtnStr = self::sanitizeIpAddress($rtnStr[0]);<br /> }<br /><br />return $rtnStr;<br />}<br /><br />//---------------------------------------------------<br /><br />/**<br /> * Returns the sanitized remote user and proxy IP addresses.<br /> *<br /> */<br />public static function getIpAndProxy()<br />{<br />$xForwarded = self::getXForwardedFor();<br />$remoteAddr = self::getRemoteAddr();<br /><br />if ($xForwarded != '')<br /> {<br /> $ip = $xForwarded;<br /> $proxy = $remoteAddr;<br /> }<br />else<br /> {<br /> $ip = $remoteAddr;<br /> $proxy = '';<br /> }<br /><br />return array($ip, $proxy);<br />}Userhttps://www.blogger.com/profile/11557173689529910046noreply@blogger.comtag:blogger.com,1999:blog-865923359735383241.post-11867400198694388642012-06-08T19:32:47.075-06:002012-06-08T19:32:47.075-06:00You pretty much answered your own question! :)
fu...You pretty much answered your own question! :)<br /><br />function getRealIpAddr() {<br /> if(!empty($_SERVER['HTTP_CLIENT_IP'])) //check ip from share internet<br /> {<br /> $ip=$_SERVER['HTTP_CLIENT_IP'];<br /> }<br /> elseif (!empty($_SERVER['HTTP_X_FORWARDED_FOR'])) //to check ip is pass from proxy<br /> {<br /> $ip=$_SERVER['HTTP_X_FORWARDED_FOR'];<br /> }<br /> else<br /> {<br /> $ip=$_SERVER['REMOTE_ADDR'];<br /> }<br /> return $ip; }<br /><br /><br />SourceUserhttps://www.blogger.com/profile/11557173689529910046noreply@blogger.comtag:blogger.com,1999:blog-865923359735383241.post-55890331060249432772012-06-08T19:32:42.774-06:002012-06-08T19:32:42.774-06:00Thanks for this, very useful.
It would help thoug...Thanks for this, very useful.<br /><br />It would help though if the code were syntactically correct. As it is there's a { too many around line 20. Which I'm afraid means nobody actually tried this out.<br /><br />I may be crazy, but after trying it on a few valid and invalid addresses, the only version of validate_ip() that worked was this:<br /><br /> public function validate_ip($ip)<br /> {<br /> if (filter_var($ip, FILTER_VALIDATE_IP, FILTER_FLAG_NO_PRIV_RANGE) === false)<br /> return false;<br /> if (filter_var($ip, FILTER_VALIDATE_IP, FILTER_FLAG_NO_RES_RANGE) === false)<br /> return false;<br /> if (filter_var($ip, FILTER_VALIDATE_IP, FILTER_FLAG_IPV4) === false && filter_var($ip, FILTER_VALIDATE_IP, FILTER_FLAG_IPV6) === false)<br /> return false;<br /><br /> return true;<br /> }Userhttps://www.blogger.com/profile/11557173689529910046noreply@blogger.comtag:blogger.com,1999:blog-865923359735383241.post-3484885817943576082012-06-08T19:32:39.155-06:002012-06-08T19:32:39.155-06:00I do wonder if perhaps you should iterate over the...I do wonder if perhaps you should iterate over the exploded HTTP_X_FORWARDED_FOR in reverse order, since my experience has been that the user's IP address ends up at the end of the comma-separated list, so starting at the start of the header, you're more likely to get the ip address of one of the proxies returned, which could potentially still allow session hijacking as many users may come through that proxy.Userhttps://www.blogger.com/profile/11557173689529910046noreply@blogger.comtag:blogger.com,1999:blog-865923359735383241.post-56099958302126770262012-06-08T19:32:37.618-06:002012-06-08T19:32:37.618-06:00We use:
/**
* Get the customer's IP address....We use:<br /><br />/**<br /> * Get the customer's IP address.<br /> *<br /> * @return string<br /> */<br />public function getIpAddress() {<br /> if (!empty($_SERVER['HTTP_CLIENT_IP'])) {<br /> return $_SERVER['HTTP_CLIENT_IP'];<br /> } else if (!empty($_SERVER['HTTP_X_FORWARDED_FOR'])) {<br /> $ips = explode(',', $_SERVER['HTTP_X_FORWARDED_FOR']);<br /> return trim($ips[count($ips) - 1]);<br /> } else {<br /> return $_SERVER['REMOTE_ADDR'];<br /> }<br />}<br /><br /><br />Edit: Just wanted to clarify, the explode on HTTP_X_FORWARDED_FOR is because of weird issues we had detecting IP's when Squid was used.Userhttps://www.blogger.com/profile/11557173689529910046noreply@blogger.comtag:blogger.com,1999:blog-865923359735383241.post-55024324191921503952012-06-08T19:32:36.886-06:002012-06-08T19:32:36.886-06:00The biggest question is for what purpose?
Your co...The biggest question is for what purpose?<br /><br />Your code is nearly as comprehensive as it could be - but I see that if you spot what looks like a proxy added header, you use that INSTEAD of the CLIENT_IP, however if you want this information for audit purposes then be warned - its very easy to fake.<br /><br />Certainly you should never use IP addresses for any sort of authentication - even these can be spoofed.<br /><br />You could get a better measurement of the client ip address by pushing out a flash or java applet which connects back to the server via a non-http port (which would therefore reveal transparent proxies or cases where the proxy-injected headers are false - but bear in mind that, where the client can ONLY connect via a web proxy or the outgoing port is blocked, there will be no connection from the applet.<br /><br />C.Userhttps://www.blogger.com/profile/11557173689529910046noreply@blogger.comtag:blogger.com,1999:blog-865923359735383241.post-63486371820422292402012-06-08T19:32:36.330-06:002012-06-08T19:32:36.330-06:00Even then however, getting a user's real Ip ad...Even then however, getting a user's real Ip address is going to be unreliable. All they need do is use an anonymous proxy server (one that doesn't honor the headers for http_x_forwarded_for or http_forwarded etc) and all you get is their proxy server's ip. You can then see if there is a list of proxy server ips that are anonymous, but there is no way to be sure that is 100% accurate as well and the most it'd do is let you know it is a proxy server. And if someone is being clever, they can spoof headers for http forwards. Let's say I don't like the local college. I figure out what IP's they registered, and get their ip banned on your site by doing bad things because I figure out you honor the http forwards. The list is endless. Then there is, as you guessed internal IPs such as the college network I metioned before. A lot use a 10.x.x.x format. So all you would know is that it was forwarded for a shared network.<br />Then I won't start much into it, but dynamic ips are the way of broadband anymore. So. Even if you get a user IP, expect it to change in 2 - 3 months, longest.Userhttps://www.blogger.com/profile/11557173689529910046noreply@blogger.comtag:blogger.com,1999:blog-865923359735383241.post-42042399338765475472012-06-08T19:32:32.501-06:002012-06-08T19:32:32.501-06:00Here is a shorter, cleaner way to get the IP addre...Here is a shorter, cleaner way to get the IP address:<br /><br />function get_ip_address(){<br /> foreach (array('HTTP_CLIENT_IP', 'HTTP_X_FORWARDED_FOR', 'HTTP_X_FORWARDED', 'HTTP_X_CLUSTER_CLIENT_IP', 'HTTP_FORWARDED_FOR', 'HTTP_FORWARDED', 'REMOTE_ADDR') as $key){<br /> if (array_key_exists($key, $_SERVER) === true){<br /> foreach (explode(',', $_SERVER[$key]) as $ip){<br /> $ip = trim($ip); // just to be safe<br /><br /> if (filter_var($ip, FILTER_VALIDATE_IP, FILTER_FLAG_IPV4 | FILTER_FLAG_NO_PRIV_RANGE | FILTER_FLAG_NO_RES_RANGE) !== false){<br /> return $ip;<br /> }<br /> }<br /> }<br /> }<br />}<br /><br /><br />I hope it helps!<br /><br /><br /><br />Your code seems to be pretty complete already, I cannot see any possible bugs in it (aside from the usual IP caveats), I would change the validate_ip() function to rely on the filter extension though:<br /><br />public function validate_ip($ip)<br />{<br /> if (filter_var($ip, FILTER_VALIDATE_IP, FILTER_FLAG_IPV4 | FILTER_FLAG_NO_PRIV_RANGE | FILTER_FLAG_NO_RES_RANGE) === false)<br /> {<br /> return false;<br /> }<br /><br /> self::$ip = sprintf('%u', ip2long($ip)); // you seem to want this<br /><br /> return true;<br />}<br /><br /><br />Also your HTTP_X_FORWARDED_FOR snippet can be simplified from this:<br /><br />// check for IPs passing through proxies<br />if (!empty($_SERVER['HTTP_X_FORWARDED_FOR']))<br />{<br /> // check if multiple ips exist in var<br /> if (strpos($_SERVER['HTTP_X_FORWARDED_FOR'], ',') !== false)<br /> {<br /> $iplist = explode(',', $_SERVER['HTTP_X_FORWARDED_FOR']);<br /><br /> foreach ($iplist as $ip)<br /> {<br /> if ($this->validate_ip($ip))<br /> return $ip;<br /> }<br /> }<br /><br /> else<br /> {<br /> if ($this->validate_ip($_SERVER['HTTP_X_FORWARDED_FOR']))<br /> return $_SERVER['HTTP_X_FORWARDED_FOR'];<br /> }<br />}<br /><br /><br />To this:<br /><br />// check for IPs passing through proxies<br />if (!empty($_SERVER['HTTP_X_FORWARDED_FOR']))<br />{<br /> $iplist = explode(',', $_SERVER['HTTP_X_FORWARDED_FOR']);<br /><br /> foreach ($iplist as $ip)<br /> {<br /> if ($this->validate_ip($ip))<br /> return $ip;<br /> }<br />}<br /><br /><br />You may also want to validate IPv6 addresses.Userhttps://www.blogger.com/profile/11557173689529910046noreply@blogger.com