PHP retrieving user ip, is really reliable? - php

I'm developing a system where users are identified by their IP addresses, through this php script:
function visitorIP()
{
if(isset($_SERVER['HTTP_X_FORWARDED_FOR'])){
$TheIp=$_SERVER['HTTP_X_FORWARDED_FOR'];
}else{
$TheIp=$_SERVER['REMOTE_ADDR'];
}
return trim($TheIp);
}
$ip = visitorIP();
I wonder if this is a really safe way to retrieve the ip address. I'm not dealing with credit card numbers or money, so the system does not need to be super safe, but if this script is very easy to hack that could be a problem anyway. Thanks for any help.

The method you are using to get the IP is pretty standard for an Apache web server, however REMOTE_ADDR is not a reliable method to uniquely identify a user. Also as other people have noted, any of the 'HTTP_*' headers are easy to spoof.
The big issue is that identifying a user by IP Address is just plain problematic, and generally you wouldn't do it in a large system where you expect to see lots of users. I can think of several situations off the top of my head where it breaks down:
Home network with multiple users behind a typical router. All the computers/devices behind the router will be coming from the same IP.
Setting up your program behind a load balancer that forwards requests to your PHP server. REMOTE_ADDR will be the IP of the load balancer.
Users coming through a proxy service will all have the same IP as the proxy server.
ISPs often use DHCP to assign IP addresses to their customers. While not likely, it is theoretically possible that a user's IP address could change in the middle of a session if the DHCP lease time expires/renews.
It's likely your situation could be handled a lot better using sessions. Assign a user a session token the first time you see them rather than using their IP address, and make sure the token is passed (via cookies or part of the HTTP requests) on subsequent requests. When you get the token, you can be fairly confident it's the same user (sniffing attacks notwithstanding).
As an added bonus, you can combine IP tracking with sessions to make things more robust if you feel the need. For instance, a lot of applications will often try to figure out if a user's IP has changed, and invalidate a session as a result.

REMOTE_ADDR itself is your best bet IMO. Any $SERVER var with a HTTP prefix can be changed by the client so you shouldn't really trust it. Although, some proxies will forward the user's real IP in the HTTP_X_FORWARDED_FOR header.

Personally I would only use :
$_SERVER['REMOTE_ADDR'].
As
$_SERVER['HTTP_X_FORWARDED_FOR'];
Is lot easier to fake.
Identifying people solely on IPs is not the best idea. They are in general easy to fake/dodge by somebody with who has a need/want to.

Your combination is fairly standard (we use it for IP-based electronic subscription checking), though as others have noted it's not perfect.
Note that several forwarding IPs may be specified for HTTP_X_FORWARDED_FOR; see http://en.wikipedia.org/wiki/X-Forwarded-For#Format for details.

Related

API based on user IP address

I developed an API to get all the data.
The site do not have a user registration system or anything to identify the user making a call to the API. If I could identify the user making the call, whenever someone misuse or attack the API I could even ban his IP.
I'm thinking of generating an API key based on user IP or MAC address but is it safe to do so? Any other suggestions?
First, you won't get the MAC address of the end-user. Even if you read the MAC address of incoming packets, you'll only get the MAC address of your router (which you definitely do not want to ban!)
User IPs are pretty easy to change and/or spoof (malware or confused-deputy Javascript, for example). Blocking those that make bad requests is still a good idea, but you definitely don't want to use them for authentication.
You should consider pretty much everything in an HTTP request (path, headers, and so on) attacker-controlled input and definitely not make authentication decisions based solely on information contained therein.
You mention you have a PHP backend. Why not build a system to generate API keys through that?
it is absolutely wrong, you cannot get MAC address of the user, there is no way from JS/PHP
many users behind NAT will have the same IP address for you, so you will not be able to distinguish them
You say there is no user registration system, then why would you generate an API key?
You can't have both worlds. Either the requests are anonymous, or the user registers, in which case you can provide an API key (better be using HTTPS so the keys aren't stolen), and possibly further limit by IP address range depending on your use case.
As others have answered, MAC addresses are only available on the same physical network. They do not go through routers, so they do not travel the Internet. You don't have access to anyone's MAC address outside of your physical network unless you have written a custom application that collects it (and those can be spoofed).
IP addresses can be dynamic, and some people share IP addresses based on geography, ISP, carrier, or business. Besides, many of us can easily change our IP address, so it's difficult to manage access by IP address.
There are some pitfalls and it takes extra time to manage a public API. You have to be willing to shut off an IP address or IP address range despite the fact that you may be blocking innocent and upstanding users at the same time as the abusers. If your application is free, it may give you more freedom since there is no expected level of service and no contract, but you may want to guard yourself with a legal agreement.
Many public APIs still track by IP address and implement tarpits to simply slow down requests from any IP address that seems to be abusing the system. This way, legitimate users from the same IP address can still carry on, albeit slower.
In general, if your service is popular enough that someone wants to attack it, that's usually a good sign, so don't worry about it too much early on, but do stay ahead of it. You don't want the reason for your application's failure to be because users got tired of waiting on a slow server.
Your other option is to have the users register, so you can block by credentials rather than IP address when you spot abuse.
It's not a good idea to ban an IP address for many reasons. And anyways, a hacker can spoof IP addresses, so this technique is useless.
What you can do is throttle the API calls based on the IP. i.e. limit the numbers of calls per IP per second.
You might find this helpful: http://blog.programmableweb.com/2007/04/02/12-ways-to-limit-an-api/

Login validation + IP Address validation In PHP

Login validation based on the username and password is done for the php application I have done.
I want to implement the IP address validation also.( An user can not be log in from two different IP address at the same time )
I am wondering, would this be reliable on the production environment? Because some says the Proxy address only will be get by the PHP server. Is that so?
Theres a few things to consider:
It is more than possible that different legitimate users of your system might share an IP from their ISP, this type of a setup is called NAT. Separate requests from the same legitimate users might end up coming in over different IP addresses during the same session, which is more rare but it happens. Also proxies as you mention are a real possibility as well.
So definitely think carefully about it before you implement such a feature.
You will get the IP Address with $_SERVER['REMOTE_ADDR']
I have to think longer about the proper solution but maybe you can do something with the sessions (and it's names)
http://www.php.net/manual/de/function.session-name.php
and maybe we need the data base too. maybe I will respond tomorrow again, it is 6 am :)
The proxy thing is true. Everytime a request pass through a proxy the IP change. At the end, you may be having the IP of the last proxy the petition passed.
If you need to implement IP address validation you should be keeping list IPs that are allowed to access the system, and check the client IP against it.
In case you worry about proxy servers check for the headers like HTTP_X_FORWARDED_SERVER, HTTP_X_FORWARDED_FOR to identify the origin IP address. I am not sure if this will work with socks proxy servers.

How to tell if a user on a site has a static IP?

Is there a good way to be able to tell if a user has a static IP? I want to be able to ID which users that come to my site have static IPs.
No there is not. This is information that is only found on that network.
As others have mentioned, there's no guaranteed way to tell whether a given IP address is statically or dynamically allocated.
You might be able to get 90% of the way there by leveraging the efforts of some of the anti-spam organizations out there -- for example,
Spamhaus PBL, the "Policy Block List", is a database of IP address ranges that have been identified by the responsible ISPs as addresses that should not be direct sources of legitimate email. I suspect that the bulk of this list is going to be residential end users on dialup or consumer broadband services. This is only a heuristic -- I'm sure
there are static IP blocks in the PBL, and probably plenty of dynamic IP addresses that
aren't on it, but it's about as close as you're going to get without knowing each
IP range owner's allocation policy.
If user turns on maintenance mode the system should record the user ip and from that point only allow that ip to enter, untill maintenance mode is turned off.
Above was what I needed for a website.
Below is what I used:
<?php
session_start();
if ($_SESSION[last_ip]!==$_SERVER[REMOTE_ADDR])
{
$_SESSION[ips] = (!is_numeric($_SESSION[ips])) ? 1 : $_SESSION[ips] + 1;
$_SESSION[last_ip] = $_SERVER[REMOTE_ADDR];
}
if ($_SESSION[ips]===1) { echo "Static IP"; }
else { echo "Dynamic IP"; }
?>
According to the replies posted (ages ago, sry 'bout that) it is close to impossible to achieve this.
For me it works... unless I don't get something.
Your Apache client will be delivered a packet that just tells you what the IP address is.
You can keep track of IPs and see if they are being used repeatedly, but static versus dynamic is negotiated by the network he is connecting to and not your website.
Not really, only via empirical evidence, same IP turning up repetitively - even then that's no guarantee it's the same user, unless it is matched to a user account or cookie, etc.
Whether an IP is static or dynamically allocated is not something that can be queried.
You might be able to detect the presence of NAT, because NAT "mangles" the packets. I'm not sure how NAT works exactly, I think it's based on the source port. But I think NAT might mangle other parts of the TCP header like time-to-live in recognizable ways. Not that NAT is a 100% guarantee that they have a dynamic IP, but it is often used with DHCP.
it is possible by applet .
You can create a java applet and get the ip of the local computer and $_SERVER['REMOTE_ADDR'] and math both and can identify whether it is having static or dynamic ip

PHP REMOTE_ADDR and secure sessions

One of the ways I have used to make securer sessions in the past is to also record the clients IP address and user agent at the handshake. Each time the client moves a page and calls session_start() I also check that the IP address and user agent stored is still the same to prevent hiijacking.
But if someone is connecting from say a company network then all the users will probably have the same external static IP address and they could also really easily be using the same user agent. Is there other metrics I can use which are local only to the physical machine?
Thanks
Not really in terms of generally available and reliable metrics, no. There are headers like X-HTTP-FORWARDED-FOR sent out by Proxies sometimes, but any self-respecting router won't tell the server which of its clients is accessing it.
I think the best you can do is a combination of
Session cookie
User Agent string
I wouldn't check for the IP address, first for the reason you mention, and second because some ISPs like AOL for example use proxies that can have the same client's IP change multiple times during the same session.
A "soft" security measure that comes to mind is Geolocation. If the same session cookie is being used by an IP in, say, Paris, France, and at the same time (or just an hour later) by one located in Sydney, Australia, it is possible that something shady is going on. I'm saying "possible" because there are conceivable legitimate scenarios for this - for example, an Australian in Paris switching over to their company VPN.
If you're really a lot about security, you could build something that triggers some alarm bells in such a case, or asks the user a secret question or something. There are a number of Geolocation providers, e.g. MaxMind or Geobytes. I think stuff like this is what the big leagues, global sites like Amazon, PayPal, etc. do to prevent fraud.
In addition to this I would like to add that using the user agent can also lead to problems. We've seen user agents get changed by any number of 'security' software packages and also by ISPs.
session id. were invented to be unique

Are there any php functions/libs/etc to detect if a user is behind a proxy or not?

I've been having a spam problem on my site, where people sign up and act extremely abusive to other users of my site. I can easy IP ban them, except they always come back under a different IP address through a proxy or TOR.
So I was curious if there are any php classes or functions that can look up the IP and determine if its a genuine user, or someone behind a proxy, in which case it would muzzle their accounts upon registration.
Many legitimate users will come to you through proxies - are you sure you want to filter all of them out? For example:
ISPs that run caching proxies for all their users
People on corporate networks
To answer your question, checking for the X-Forwarded-For or Via headers is probably your best bet.
Following RichieHindle's answer, I'd suggest some kind of profanity filter/detection - detect the unacceptable behaviour and suspend the accounts. Use of a proxy could definitely influence weight of decisions made by the filter/detector!
Actually stopping them is difficult, but if their nasty content doesn't get published they'll soon give up.

Categories