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
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 am making a script that show popup only one time , then it will never show again on that device..
How is it possible to do this?
I have already tried by using cookies, but these can be deleted by the user and so the effect is limited.
Another question is what is wholly unique per device, IP Address or MAC Address?
The only way is a cookie. There's nothing 100% uniquely identifiable about a machine that you have access to in an HTTP request. Yes, cookies may be deleted by the user. This is deliberate, live with it.
The 2 options that are most obvious are either Cookies or a flag on an Account (if your users are authenticated).
Even though you've mentioned that cookies can be deleted, it's still a reliable form of saying "I have done something for this client before". If the user deletes the cookies then there's a high chance they know what they're doing, and should be expecting to have to repeat tasks (such as logging into other websites too).
If your users are authenticated (namely: they have to login to your site/service), then you can easily store a flag saying that the user has already been shown the notification.
That way is of course more reliable, but relies on authentication. Long story short: You need to take what you can get, and cookies are your best bet to have some form of unique device ID.
Regarding your other question: Nothing is unique in reality. MAC Addresses (which you wouldn't have access to anyway) can be spoofed, and IPs can be shared.
Neither. Millions of Internet devices have 192.168.0.2 as their IP. So that's not unique. And MAC addresses aren't Internet things at all, they're Ethernet things.
If you explain your outer problem in more detail, there's probably a solution. But it sounds strangely bogus from what you've said already. The same person on two different devices should get the popup twice? But with two people on the same machine, the first person should get it only? It's hard to imagine a use case where you should go out of your way to ensure that.
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.
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
I'm currently in charge of setting up a polling system (using PHP).
Now for it to be as secure and objective as possible, it's important that a visitor can only vote once. I'm thinking of validating the polls by visitor's IP (there can be only one vote from one IP), and maybe throw in a captcha test to be sure that no bots can get in once they've passed the IP validation for some reason.
So there it is, unique-IP validation and captcha. But is this enough ? Is there a possibility that a single user can change his/her IP by using proxies or other ways I don't know of, and vote multiple times with unique IPs ?
Are there better ways to do this ? Preferably without the captcha.
Thanks in advance.
There is absolutely no way to be sure a user has voted once when it's a public voting system, where no login is required.
Checking the IP is not a good idea for several reason. As described in other answers, lots of networks are behind one ip, and users can just use an other pc with different ip and vote again.
OpenId
Use OpenId to identify the user and check if they have already voted.
Register users
Optionally you could allow users to register themselves if they do not have an openid account.
To implement a secure system, where session spoofing, and thus multiple voting, is made difficult read this
You can't create a 100% secure voting system.
If it's based on registration/IP/cookie, the user can create a new user/get an another PC/delete all cookie.
But you can try it with auto prefilter + administrator as postfilter workflow:
Prevent multiple voting with cookie (or IP / browser properties / etc.) filtering automatically.
On an admin view, the administrator can parse and delete votes by hand based on IP or subnet address. This is nor a perfect solution, but with some good query (same votes in the same time intervall from the same IP/subnet) the administrator can easily delete suspicious votes.
One big drawback of this solution is the need of an administrator. But - I think - there is no perfect solution.
Unless you're going to require identity verified by CA, there is no way you can be sure, that each person votes only once. This of course would be total overkill, so the real question is: how to make multiple votes more difficult.
email with verification code. IMHO overkill, but depends on how sure you want to be.
use session to check who voted. Obviously not 100% secure, but will stop 99% of ppl.
use cookie to check who voted. Like above, some ppl will know how do delete cookies.
use POST, ignore GET.
use combination of 2 or 3 of above.
If you're going to use IP for validation, do not use just REMOTE_ADDR, combine with whole X-Forwarded-For. This way you won't block people connecting through same proxy.
Don't go with the way of unique Ip. There are a lot of case scenario where a lot of users have the same ip (i.e. italian isp fastweb, large corporations, etc). Also, if user has dynamic ip it can change it's own ip address every time he likes...
One of the best ways should be using email address and cookies. User will be able to vote multiple times (you can't avoid this), but at least it will take them some time for each vote.
for a similar project i did 2 verifications ...
i placed a cookie and also saved on the server a hash from users ip + user agent.
this seemed to be pretty effective since even if there are more people that use the same IP the hash with user agent will be different most of the times since it differs for same browser depending on the operating system and other extensions installed.
There is no fool proof way for preventing multi votes. Checking cookie is anothr option.
Regarding Validatin the ip address. What if the user is from a net work which is used by many users?