Can IP change during session?
What about different engines (PHP, Django, Ruby, etc) ?
PS: I don't quite understand what is 'dynamic ip' and how they are held by internet providers... And how sessions are broken...
Update:
Should I track IP change for security? I'm currently working with PHP, so if the built in session system lacks security, please provide some code and algorithms
IPs can change at any time - the idea behind HTTP is that each request is independent.
There are only around 3 billion IPv4 addresses available worldwide. Some ISPs (most of them, actually) therefore assign IPs dynamically for each connecting client - so that when this client disconnects, the IP can be reused for someone else.
As far as 'sessions' are concerned - it all depends on how the state is held. The most sane approach is to use a cookie - which allows you to connect from arbitrary IP, on an arbitrary medium - at which point, you should not be concerned with IP layers of the HTTP.
But again, people are known for doing weird stuff, like using IPs for things they were never meant (in the OSI/IETF sense) for - like identification, authentication, etc.. This is doubly bad, because one IP can commonly mean many customers - for instance, your entire household likely shares the same public IP - what if you and your partner both visit the same site? How can the server tell the two of you apart?
#update
No, you shouldn't track IP changes for 'security' - the only exception is if you can deal with geoIP features, and want to disable/annoy users of various anonymisation services.
Basically, if your users connect directly (and not via proxy/TOR), it would be very likely that they will connect again from a nearby location. If your users connect once from the US, once from Russia - that can mean either that these are two different people (one of whom might've stolen the credentials), or that the user uses an anonymiser of sorts.
If the site is a high-value target (banking, finance, central credentials (think Google Account)) - you could geo-lookup the IPs and compare if the distance changed by more than 100km in under an hour more than twice - this is likely fishy, and you can bug the user for extra credentials.
Otherwise, you could display the last few IPs - but it's likely an icing on the cake with little real value.
#update2
Security is a tricky subject - whenever you're dealing with it, you need to answer two fundamental question:
Security of what:
what is so valuable that needs protecting
Privacy of users
Permissions granted to a user
Assets (physical or virtual)
And security against what:
What is the attack scenario you are concerned about
Cookie hijacking (firesheep) (just use SSL and be done with it for the most part - there is no way around the problem that HTTP is unencrypted and often over public radio)
Taking over accounts (require additional credentials for really sensitive stuff)
Defacing?
Just thought I'd add a comment to this though it is an old thread.
An IP for a visitor to your website can change for instance when the visitor decides to switch from mobile data to wifi. Maybe he wants to download something from your site and thinks it would be better to use wifi for it. The session can remain the same during the process.
1) Yes, an IP address can change during a session.
3) No, I can't think of any security benefit of "tracking IP changes".
2) A "dynamic IP address" is simply the opposite of a "static IP address:
a) With dynamic IP's ("DHCP"), the network assigns the address to a host (typically, when you boot up).
b) With static IP's, you configure the host with a fixed, unchanging address.
c) Dynamic IPs are the norm. They're easier to administer, they relieve the end user of having to do any network configuration, and they mitigate the risks of conflicting network addresses.
Here is a good link that might make the distinction between "static" and "dynamic" addressing clearer:
http://compnetworking.about.com/od/workingwithipaddresses/qt/staticipaddress.htm
Related
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/
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.
I'm upping my security on my website, because some of my users were
questioning the security, but all I can say is no one can view your
password (dual hashed using SHA-512 and then md5), but they reply, but what if they get into my account they
can change my password and play around with my account.
So I'm going to up my security kind of like Steam's security where you can't login to a
new computer without them sending you a random key. I'm trying to think of a way to do it, so I've got it so it will store a little array in my database that will have all the computers that the user has logged in to with.
But I need some data so that my script can check it but I'm not quite sure what data, I was thinking of the IP address but you can't get it without an external source e.g whats my ip and other sites like that. I need some data that doesn't change with the same browser/computer.
So question is, I need some data that is unique to the browser he/she is using but it does change if he/she is on a different computer or browser.
It is possible to implement some security in your web application on IP level. As a matter a fact, for example, in the company I am working it's possible to log in with "Administrator" account only from the devices connected in company network - a given range of IP address.
If you want to implement this technique for each user, you will meet a lot of issues because your users can be behind some proxy server, that is changing their IP address on each log in or on given interval of time.
They are different types of proxies and you can detect when the user is using some of them, and then retrieve the real IP address of the user - check this HTTP headers:HTTP_X_FORWARDED_FOR, HTTP_VIA AND REMOTE_ADDR EXPLAINED and more specific this X-Forwarded-For one.
Any way, they are a lot of techniques to hide you IP address like proxy servers and applications like HideMyAss that makes the whole thing pretty easy.
Anyway, even your users send to you a specific set of email address that you will store in your database and check if the users are connected to your application using them, the same possibility for abuse, using your account (as the passwords) is faced again. The IP addresses will be just an other field in your database table. So, if anyone can change the passwords, he might be able to add an other new IP to the IP list that your are checking.
I think that the best think to do, is to implement such IP security only for your administrator account. Then, you and your clients will be calm that no one can join with it and change their passwords.
Don't know if you have many users, I never did this in a practical application but played with bouncycastle a long time ago. Had a similar problem with a 3rd party provider providing services to out company with IP filtering but Dubai offices were refused because some proxy gets in there that doesn't provide forwarded for and has a wide IP range.
Here is the option I was thinking of but never applied:
Making a self signed key for each/all/groups of client to import and and importing the public part of that in your server store, then do not allow anybody there unless they have a key that's imported in your server keystore.
Maybe if you serve companies that use a proxy you can have the proxy serve the key.
What is the best way to generate a 'fingerprint' of user unique-ness in PHP?
For example:
I could use a user's IP address
as the 'fingerprint', however, there
could be multiple other users on the same IP
I could
use the user's IP + user agent as
the 'fingerprint', however, a single user
could simply swap from safari to
firefox and again be seen as being unique
Ideally, the fingerprint so label the 'machine' rather than browser or 'ip' but I can't think of how this is achievable.
Open to ideas/suggestions of how you uniquely identify your users, and what advantages/disadvantages your method has.
Easiest and best way: use phps session-management - every client is given an ID, stored in a cookie (if enabled) or given as a get-variable on every link and form (alternatively you could set a cookie on your own). But, this only "fingerprints" the browser - if the user changes his browser, deletes his cookies or whatever, you can't identify it anymore.
Identifying every client by IP address is usually a bad idea and won't work. Clients that use the same router will have the same IP addresses - clients connected through a proxy-pool could have another IP address with every page load.
If you need a solution that can't be manipulated by the client in an easy way, try to do a combination of the following, using all that are supported by the clients browser and compare them on each page-load:
"normal" HTTP Cookies
Local Shared Objects (Flash Cookies)
Storing cookies in RGB values of auto-generated, force-cached PNGs using HTML5 Canvas tag to read pixels (cookies) back out
Storing cookies in and reading out Web History
Storing cookies in HTTP ETags
Internet Explorer userData storage
HTML5 Session Storage
HTML5 Local Storage
HTML5 Global Storage
HTML5 Database Storage via SQLite
There's a solution called evercookie that implements all of this.
There's something else to take in account, the public IP Address of a user is something that also can change in every page load.
There are multiple organizations that switch public IP's in they routers to balance traffic.
Achieving 100% reliability is not guaranteed, but combining some common methods can give you meaningful results
Users generally don't switch browsers. Over-complication in your algorithm only to reach engineering perfection is not worth the effort.
You certainly belong to the top 100 websites if you can expect multiple users from the same IP. Don't take it personal, but you're just not that popular.
Take the simplest possible route that could work and adjust over time if it seems necessary.
I have three different computers, various handheld devices, and many of them have different browsers installed. I use all these interchangeably at home take them with me other places so, basically, on various IP addresses. What I'm trying to point out is that fingerprinting a browser or a machine for that matter is never going to be foolproof if your goal is to block a person.
I recommend you take a different approach. Judge based on the inconclusive information you have available that suggests the identity of your banned user (same IP or same user-agent if it's a uncommon one or else some of the javascript browser fingerprinting methods such as available fonts, available plugins, non-standard window size, etc.) and require of those suspect visitors some higher form of identity verification -- such as oauth with Facebook, Google+, or Twitter. Then you can look to see if that social media account is genuine or created just to circumvent. There are also phone verification APIs in case your user base isn't social-media savvy and depending on how valuable it is to you that users don't circumvent banning.
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