1

Here is my table structure:

// users
+----+--------+------------------------+------------------+-------------------------------+
| id |  name  |          email         |     cookie       |    /* some other columns */   |
+----+--------+------------------------+------------------+-------------------------------|
| 1  | Jack   | jack0948@example.com   | ojer0f934mf2...  |                               |
| 2  | Peter  | P_2009@example.com     | ko4398f43043...  |                               |
| 3  | John   | mx_pro34@example.com   | 0243hfd348i4...  |                               |
+----+--------+------------------------+------------------+-------------------------------+

The cookie column contains a string (the cookie which keeps the user logged in) that is also set into user's devices. As you see, I have just one string (as the cookie) for each user. So all user's devices have an identical cookie.

Most professional programmers tell me:

It would be safer if each device had its own cookie (the cookie of each device should be different than the cookie of other devices, not a constant cookie for all devices)

Well, why? What's wrong with having an identical cookie for all devices? Also as you see I have just one record for the cookie in the database. So if I update that record for a new device, then the previous device(s) will be logged out.

EDIT: Imagine the following scenario (based on different cookies for different devices):

Alice logs in to my site on her computer at home, and stays logged in. Later she logs in on a computer at school as well, and dont sign out when she is done, but she forgets to sign out. She goes home and wants to sign out from her account at school. How can she do that?

  • 1
    Didn't you ask this already and I answered here? i.e. The problem with your approach is that you cannot revoke the token from individual devices easily.. To logout all devices you simply delete all server-side tokens for the user, so to logout one you just delete the corresponding entry for that device. – SilverlightFox Jun 28 '16 at 8:41
  • @SilverlightFox to revoke the token for each device, I can hit remove the cookie from that device, why should I remove the token which is stored in the database? – stack Jun 28 '16 at 12:01
  • Because that isn't secure. Say that one of the tokens has been stolen by an attacker (say in the simplest case the cookie value is copied from the machine the user left unlocked, although there are many other methods of achieving this depending on how vulnerable your system is), you will want to prevent this attacker from using the stolen cookie. Therefore, the server-side value will need to be deleted. Also see my comment here. – SilverlightFox Jun 28 '16 at 12:35
  • @SilverlightFox I see .. (however, the possibility of what you said happening is pretty low) – stack Jun 28 '16 at 12:45
  • How can you be sure there are no session management vulnerabilities in your app? e.g. Session Fixation. Check with the cheat sheet here. You should always provide a method to revoke sessions server-side so any exposure is limited should the worst happen. – SilverlightFox Jun 28 '16 at 12:48
4

The problem

Imagine the following scenario: Alice logs in to your site on her computer at home, and stays logged in. Later she logs in on a computer at school as well, but signs out when she is done. What happends when she gets home?

To make this system work, you would need to set the cookie column to NULL on logout. But that would log her out from all devices. That would be very annoying if you for instance want to stay continously logged in on your phone. So as long as you actually invalidate sessions server side on logout (you should always do that) this is more of a usability issue than a security issue.

Solution #1

So what would your table structure look like if you allowed multiple sessions per user? First, drop the cookie column from the users table. Then create a new table called sessions like this:

+------+------------------+
| user |     cookie       |
+------+------------------+
| 1    | ojer0f934mf2...  |
| 2    | ko4398f43043...  |
| 2    | 34fjkg3j438t...  |
| 3    | 0243hfd348i4...  |
+------+------------------+

Note that the second user has two different active session.

There should be a timestamp in there somewhere also, so that you can terminate the session after X hours. Even if you have a max-age on the cookie, you should always terminate sessions server side as well to mitigate the effects of session theaft.

Solution #2

No need to store session identifiers in a database. Just use PHP's built in session handling and you will not have to worry about generating ID's, setting cookies, etc.

Signing out from different devices

Conserning your edit about how to let Alice log out from school if she forgot to do it: Include a feature that lets her log out from all devices. Facebook, for instance, has a feature like that. Or if you don't want to waste energy implementing that, just instruct users to change their password - a well implemented password reset function should terminate all the users active sessions anyway.

In the database setup, ending all sessions would be the equivalent of running this:

DELETE FROM sessions WHERE user = :id
  • 1
    BTW your second solution means my website shouldn't has "remember me" option? And user have to log in every time? – stack Jun 27 '16 at 15:12
  • @stack My solution could work both with and without the remember me option. See my edits as for answer to your edits. – Anders Jun 27 '16 at 15:14
  • Ah, do you mean when Alice changes his password, I have to remove all her cookies stored ? (I'm talking about your first solution) – stack Jun 27 '16 at 15:18
  • @stack Yes, that is considered good practice. – Anders Jun 27 '16 at 15:19
  • Alright .. and thanks again for your great answer. Just still I don't understand your second solution. What's that mean exactly? It doesn't need any database, so every time user needs to log in (enter his user and password). Is my understanding correct? – stack Jun 27 '16 at 15:21
1

Cause it's easier to use a session hijacking attack...

More about it here https://www.owasp.org/index.php/Session_hijacking_attack

  • 1
    Why is it easier? – Neil Smithline Jun 27 '16 at 18:55
  • Because you can fix each session to a single device so if a diffrent device is trying to use the same session (lets say a hacker's computer) you can stop that attack by denying the "new" session to the new device and force it to use valid credentials just like facebook, google and every other internet app does. – Solrac Jun 27 '16 at 22:28
  • Of course if your app doesn't need to prevent session hijacking you can use the same cookie for all the users if you want... – Solrac Jun 27 '16 at 22:29
  • So it's more secure if you incorporate IP tracking into your session management solution. That seems valid to me – Neil Smithline Jun 27 '16 at 22:45
  • Yes, you can incorporate IP address, session id, user agent and a random generated string at login as a constraint to help mitigate session hijacking. I like to track each request, mark the digested constraint as "used" and then assing a new one, this way if a user becomes a victim of session hijacking the seccond user will trigger a lock on the victim's account when the constraint missmatchs the one on my database. – Solrac Jun 28 '16 at 2:16

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.