views:

2035

answers:

5

I want my website to have a checkbox that users can click so that they will not have to log in each time they visit my website. What is the best way to implement this? I know I will need to store a cookie on their computer, but what should be in it? Is there anything I need to watch out for to keep this cookie from presenting a security hole?

+2  A: 

Store their UserId and a RememberMeToken. When they login with remember me checked generate a new RememberMeToken (which invalidate any other machines which are marked are remember me).

When they return look them up by the remember me token and make sure the UserId matches.

jonnii
+1  A: 

I would store a user ID and a token. When the user comes back to the site compare those two pieces of information against something persistent like a DB entry.

As for security, just don't put anything in there that will allow someone to modify the cookie to gain extra benefits. For example, don't store their user groups there or their password. Anything that can be modified that would circumvent your security should not be stored in the cookie.

dragonmantank
+21  A: 

Improved Persistent Login Cookie Best Practice

You could use this strategy described here as best practice:

  1. When the user successfully logs in with Remember Me checked, a login cookie is issued in addition to the standard session management cookie.
  2. The login cookie contains the user's username, a series identifier, and a token. The series and token are unguessable random numbers from a suitably large space. All three are stored together in a database table.
  3. When a non-logged-in user visits the site and presents a login cookie, the username, series, and token are looked up in the database.
    1. If the triplet is present, the user is considered authenticated. The used token is removed from the database. A new token is generated, stored in database with the username and the same series identifier, and a new login cookie containing all three is issued to the user.
    2. If the username and series are present but the token does not match, a theft is assumed. The user receives a strongly worded warning and all of the user's remembered sessions are deleted.
    3. If the username and series are not present, the login cookie is ignored.
splattne
see also:http://stackoverflow.com/questions/549/the-definitive-guide-to-website-authentication-beta#477579 you should NOT read the 'improved' version
Jacco
The problem with this is that you expose the username in the cookie, though this is what Gmail does. Why do you need both a series ID and a token? Wouldn't a bigger token be fine?
Yar
@yar: no it wouldn't be fine and the article describes why
cherouvim
@cherouvim, thanks for that. Why?
Yar
@yar: the article describes in detail. the series is being used to mitigate the results of a cookie theft.
cherouvim
Also make sure that changing the user's password or password recovery information requires the original password. If the cookie is compromised, the attacker cannot prevent the original owner from accessing the account.
Exception
can anyone explain when will the series identifier change? if never, then storing the username encrypted and the token will suffice?
altvali
+1  A: 

You should be careful with "remember me" because of XSS If you badly need this functionality I give my vote to splattne suggestion.

Chobicus
+3  A: 

Investigating persistent sessions myself I have found that it's simply not worth the security risk. Use it if you absolutely have to, but you should consider such a session only weakly authenticated and force a new login for anything that could be of value to an attacker.

The reason being of course that your cookies containing you persistent session are so easily stolen.

4 ways to steal you cookies (from a comment by Jens Roland on the page splattne based his answer on):

  1. By intercepting it over an unsecure line (packet sniffing / session hijacking)
  2. By directly accessing the user's browser (via either malware or physical access to the box)
  3. By reading it from the server database (probably SQL Injection, but could be anything)
  4. By an XSS hack (or similar client-side exploit)