What is the most accurate way to get user's IP address in 2017 via PHP?
I've read a lot of SO questions and answers about it, but most of answers are old and commented by users that these ways are unsafe.
For example, take a look at this question (2011): How to get the client IP address in PHP?
Tim Kennedy's answer contains a recommendation to use something like:
if (!empty($_SERVER['HTTP_CLIENT_IP'])) {
$ip = $_SERVER['HTTP_CLIENT_IP'];
} elseif (!empty($_SERVER['HTTP_X_FORWARDED_FOR'])) {
$ip = $_SERVER['HTTP_X_FORWARDED_FOR'];
} else {
$ip = $_SERVER['REMOTE_ADDR'];
}
But as I've read a lot, I have seen that to use X_FORWARDED_FOR
is unsafe, as the comment below highlights:
Do NOT use the above code unless you know EXACTLY what it does! I've seen MASSIVE security holes due to this. The client can set the X-Forwarded-For or the Client-IP header to any arbitrary value it wants. Unless you have a trusted reverse proxy, you shouldn't use any of those values.
As I didn't know EXACTLY what it does, I don't want to take the risk. He said it is unsafe, but did not provide a safe method to get user's IP address.
I've tried the simple $_SERVER['REMOTE_ADDR'];
, but this returns the wrong IP. I've tested this and my real IP follows this pattern: 78.57.xxx.xxx
, but I get an IP address like: 81.7.xxx.xxx
So do you have any ideas?
I use this code, and it works for me. Take a look to it.
Here, a working example. Hope it helps!
How about this one -
From a security POV, nothing but
$_SERVER['REMOTE_ADDR']
is reliable - that's just the simple truth, unfortunately.All the variables prefixed with
HTTP_
are in fact HTTP headers sent by the client, and there there's no other way to transfer that information while requests pass through different servers.But that of course automatically means that clients can spoof those headers.
You can never, ever trust the client.
Unless it is you ... If you control the proxy or load-balancer, it is possible to configure it so that it drops such headers from the original request.
Then, and only then, you could trust an e.g.
X-Client-IP
header, but really, there's no need to at that point ... your webserver can also be configured to replaceREMOTE_ADDR
with that value and the entire process becomes transparent to you.This will always be the case, no matter which year we are in ... for anything related to security - only trust
REMOTE_ADDR
.Best case scenario is to read the
HTTP_
data for statistical purposes only, and even then - make sure that the input is at least a valid IP address.