views:

80

answers:

6

I'm developing a site where you are not allowed to login on multiple accounts on one computer, but I do not know how to do this. The method has to be:

  • Cross-platform (can be used on Windows/Mac/Linux clients).
  • Browser independent.

This is to avoid some users exploiting multiple users to gain unfair advantages, while still allowing two persons on a local network to connect as long as they are on different computers.

Any tips?

+2  A: 

You could try using a persistent Cookie, like "Evercookie" http://samy.pl/evercookie/, that way you'll identify each computer with a distinctive cookie and it'll be persistent.

Then all what you need to do is link that cookie to your session handling schema.

Edit: As Claudiu pointed out, you'll also need to check the user has JS enabled, and deny access in the case it's disabled.

All methodologies using IP address for verification have 2 issues: - Anyone could use a proxy and bypass them - It wont work with on NAT'ed enviroments

Pablius
Users can disable Javascript, therefore your method can be bypassed
Claudiu
Evercookie looks promising. People needs to have javascript enabled to use the site anyway, and it is still better than using Java, which a lot more users have disabled.
Will delete my answer as this is exactly the same. Only relevant additional info: "Since cookies are per browser and not per computer you could maybe restrict to usage of one specific browser per IP" and let us know your progress!
sunn0
@sunn0 That would force people to use different browsers in worst case. I'll let you know if I find a method that isn't a hassle for either me or the users.
It would force users on the same IP to use the same browser if they are not using the X-Forwarded-For header if you combine the answers suggested. I think this is as good as it gets.
sunn0
A: 

The only way I see is to check by IP, if you have the $_SERVER['REMOTE_ADDR'] already connected, then don't let any other one. Of course, in some cases you can have the same IP on two different PCs, but that's the most secure way, so your users should be aware of it.

Claudiu
But that wouldn't enable say two roommates to be connected at the same time with different accounts, which I want to offer to my users.
Yes, but then you would have to quit the idea that nobody would be able to break in to your system.. like cheat on the system
Claudiu
I do not believe that my system wont be breakable if you really want to, just enough that is discourage people from doing so. Using proxies would not help if the computer uses the same cookie no matter the browser on the same computer, which seems the route I have to go down it seems.
A: 

Theres several factors that you need to look at.

Making sure that there's only 1 session per ip address is going to be the best way to do this, the only down side to this is if the user does not log out you may have issues.

What I would do is

Store logged in users in a table and track there last activity, if your site is a site where the user may not change page for some time then you should set up a javascript heartbeat witch just ping's your server from the browser so that PHP is always up to date.

If user A is logged in and another attempt from a different IP tries to log in, then you should deactivate user A's logged in status and allow user B to start a new session.

you should also track the IP Addresses a user uses to log in, so that you can have an incremented table like

user_id         ip                hits
--------------------------------------
1             xxx.yyy.zzz.244     6
1             xxx.yyy.zzz.224     4
1             xxx.yyy.zzz.264     1
1             xxx.yyy.zzz.124     1
1             xxx.yyy.zzz.174     1
2             aaa.bbb.zzz.678     3
.....

This way if a user A is logged in and User B attempts, you can run a check to see if this IP has been used before, if it has then you just run a direct logout, otherwise you can ask a secret question provided upon registration to help with the security side of things

RobertPitt
This still doesn't allow two from the same IP to be connected as long as they are on two different computers.
you cant have simultaneous connections from the same ip, with different consoles.
RobertPitt
The problem isn't to only allow one session per IP (which wont be forced) or not logging in from different locations at the same time (which isn't going to be possible). The problem is only allowing one session per computer. Multiple computers under the same network should be able to login, but only one active session per computer.
A: 

You could just put a bit column (IsLoggedIn) in your database indicating if a person is currently logged in or not?

Things that wouldn't work and why:

  1. IP: Everyone inside a local LAN behind a router will appear to your website as having the same IP address.

  2. Cookies: They are browser dependant. A cookie in e.g. IE will not be known in Firefox.

Peter
Checking if a user is logged in wont help if they use multiple accounts. I knew that those wouldn't work, so, what I want to know, what else would work?
+1  A: 

The only way would be to distinguish by client's IP address, as others mentioned here, however if your users are going to be behind a proxy things get a lot trickier.

There is a de-facto standard among proxies to add an HTTP header called "X-Forwarded-For" which reflects the client's internal IP. The pair of $_SERVER['REMOTE_ADDR'] plus the value of X-Forwarded-For in principle gives you unique identification of a client's machine. However, X-Forwarded-For can be easily forged by an advanced attacker who uses a real IP address.

To get the value of X-Forwarded-For in php:

$headers = apache_request_headers(); 
$full_client_id = $_SERVER['REMOTE_ADDR'] . '|' . $headers["X-Forwarded-For"];

$full_client_id, which may look like e.g. '123.1.2.3|192.168.1.1' will give you that almost-reliable identification to be stored in your session data and compared against every newly created session.

This will protect you at least against very obvious misuse by non-advanced users.

mojuba
Usefull, proves that it can be done, but unfortunately, as you state, it can be forged by an advanced attacker. Which makes this method useless.
+2  A: 

Edit: I consider my answer a hack and would love to see a best practice alternative.

As much as I hate them, checking against Flash Cookies would work here. Most users don't know they are even on the computer so you don't have to worry much about them getting deleted. Go to this link and see how many have been sitting on your computer for ages without your knowledge: Flash Cookie Manager.

I don't think Flash works with iPhone though, but you didn't mention it.

Here is adobe's take on the flash install base. Wikipedia also has a take on flash penetration.

JMC
This really seems to be the answer to my problem, going to investigate it more throughly. If numbers from Adobe are to be believed, almost everyone has Flash activated. Should be able to come up with something that would allow iPhones or similar to connect. I'll see what I can do with this information.
That's quite a scary number of unknown cookies... **dammit**. (+1 for showing me how much I've got stored on my system that I never knew about).
David Thomas