Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

PHP most accurate / safe way to get real user IP address in 2017

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?

like image 855
Infinity Avatar asked May 20 '17 11:05

Infinity


People also ask

How do you get the users IP address in PHP?

Using getenv() function: To get the IP Address,we use getenv(“REMOTE_ADDR”) command. The getenv() function in PHP is used for retrieval of values of an environment variable in PHP. It is used to return the value of a specific environment variable.

How can I get static IP in PHP?

The simplest way is to use $_SERVER with 'REMOTE_ADDR', it will return the user's IP address who is currently viewing the page. Example using ['REMOTE_ADDR'] to identify the server's IP address in PHP.

Can you forge IP address?

Internet Protocol (IP) spoofing is a type of malicious attack where the threat actor hides the true source of IP packets to make it difficult to know where they came from. The attacker creates packets, changing the source IP address to impersonate a different computer system, disguise the sender's identity or both.


2 Answers

Short answer:

$ip = $_SERVER['REMOTE_ADDR'];


As of 2021 (and still) $_SERVER['REMOTE_ADDR']; is the only reliable way to get users ip address, but it can show erroneous results if behind a proxy server.
All other solutions imply security risks or can be easily faked.

like image 102
Pedro Lobito Avatar answered Sep 21 '22 12:09

Pedro Lobito


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 replace REMOTE_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.

like image 22
Narf Avatar answered Sep 22 '22 12:09

Narf