Take the 2-minute tour ×
Programmers Stack Exchange is a question and answer site for professional programmers interested in conceptual questions about software development. It's 100% free, no registration required.

I've read many, many, many posts on how "you're probably storing passwords wrong". They are always referring to storing passwords on a server into which a user is logging; they basically rehash (pun intended) ubiquitous advice like make sure to salt the passwords, etc. etc. However, I've never seen an article on best practises for storing passwords on a client so that the client doesn't have to log in manually every time they want to log in; the "remember me" feature.

Many pieces of software have this feature, from browsers to programs like Dropbox.

I did read an old article recently about how Dropbox was storing an ID on your computer that you could just copy/paste to another computer and start Dropbox and be logged in as the device you got the ID from; no login, no nothing, and full access to the Dropbox account. This seems like a really stupid design, but I can't think of any better way to do it.

I'm not even sure how to avoid storing something like a cookie in plain-text. If you encrypt it, where do you store the key to decrypt it?

The only way I see to not introduce security vulnerabilities is to remove the autologin feature and make the user type their password every time they want to use a service, but that's a usability struggle and users are spoiled to expect not to have to do that.

What can I read about locally storing credentials safely to implement the automatic login feature? If the principles are too simple for an entire article, what are they? The software in question should not depend on features not present on all platforms (like the "keychain" some linux distributions have).

share|improve this question
1  
It is about what you trust. If you don't trust the machine store the ID then that is your issue. If you trust the keychain then that is the maximum security you will get. Off course you could add some custom safety like detecting device hardware or something but it's all fake-able so you cannot know in the end. It is out of your control. Off course stupid things like saving clear text passwords excluded. –  Luc Franken Jun 5 '13 at 8:52
    
@LucFranken how can you trust the machine? Someone can exploit you like they did dropbox. Also I would trust the keychain but not all computers have one, and Windows never does (AFAIK). And if you're storing passwords, how do you avoid storing them in clear-text? If you encrypt them then where do you store the key to decrypt it? –  Jay Simon Jun 5 '13 at 8:56
    
That's exactly the issue, you cannot trust it. The user can only define to trust it. That takes into consideration user understands how secure his machine is. Write a virus getting data from Dropboxes is just possible. Same with locally stored keys and other local data. You can help to make it more secure (think about apps which require a 5 number code) but in the end it's local and out of your control. –  Luc Franken Jun 5 '13 at 9:00
    
@LucFranken is it just me or does autologin seem like a ubiquitous feature? If it is, why haven't people written about how to do it right? –  Jay Simon Jun 5 '13 at 9:02
    
It is a so common requirement though some more enterprise software does not allow it. For example SalesForce allows to only save the username, not the password. Let's put clear btw. that you don't have to store the password at the client for a login. You can store a random hash which corresponds to a hash on the server. –  Luc Franken Jun 5 '13 at 9:06

4 Answers 4

The usual way is:

  • When the user logs in, store a session ID in a cookie on the client's computer (not the username or password).
  • Tie session to IP address, so an individual session ID only works with the computer it was started on.

Depending on what framework you are using to develop your site, this behavior may be available as a built-in feature.

Note that, because the HTTP protocol is stateless anyway, there is actually no functional difference between keeping someone logged in during a single session of using the website and "auto-login" the next time they use the site; it is solely a matter of how much time you allow before the session expires.

Update: Also, consider using HTTPS for increased security, obviously.

share|improve this answer
    
Tying it to an IP address doesn't help much because someone might have a computer that's behind the same firewall as you are though. –  Jay Simon Jun 5 '13 at 9:16
1  
@JaySimon, I wouldn't say "doesn't help much". The number of computers behind the same firewall as you is vastly smaller than the number of computers in the world. It is about limiting your potential exposure to attack, and this limits it greatly. This is a standard approach, and I really don't think there is much you can do beyond it. If someone has the same IP address as the user and manages to obtain a session ID, that person will be indistinguishable from the user from the server's perspective. If you are have any kind of log-in on your site, you are exposed to such an attack. –  dan1111 Jun 5 '13 at 9:22
2  
Do you think such an approach will be annoying to users on mobile phones who's IP address may change often? –  Jay Simon Jun 5 '13 at 9:26
    
@JaySimon, if it happened within a session the user would experience it as a sudden log out, which certainly would be annoying. I don't know how often they actually change, though (a quick Google search doesn't reveal a definitive answer). I would not be too worried about it unless the IP was likely to change while they were actually using it. –  dan1111 Jun 5 '13 at 9:42
    
Restricting the session to the IP isn't really realistic as said. Users changes location often. With mobile phones but also with laptops; for example flex working. The best you can do there is some GeoIP checks combines with the time to travel that distance; like Gmail does. –  Lode Jun 7 '13 at 20:06

It's actually not that hard. First store a cookie with this format:

userID.token

You can use an sha1 hash for the token. Then in your remember_me_tokens database table store userID, a bcrypt hash of the token and the time the token was generated.

Then when someone visits your site, check to see if the cookie is set. If the cookie is set then see if there's a valid row for it in the database within the last 7 days say. If there's a valid row in the database for the cookie then set the session to indicate that the user is logged in and also delete the matched cookie/database row and generate a fresh cookie/token/database row.

If they log out then delete the cookie.

Run a cron job to prune remember_me_tokens that are older than say 7 days.

share|improve this answer
    
What prevents someone from copying this key and pasting on their machine and getting access to the account without the username or password? –  Jay Simon Jun 5 '13 at 9:07
    
how are you going to get the key? it's stored locally on someone's computer. –  Ryan Jun 5 '13 at 9:11
    
you walk up to the computer and open the file where it's stored :) –  Jay Simon Jun 5 '13 at 9:14
1  
@JaySimon This same argument can be made for somebody who logs in and walks away for 5 minutes without locking their computer, or clicks Remember Me and somebody jumps on their account password. If you can accept this possible security situation then the convenience of it is nice but then that is why you don't see a Remember Me feature on the CIA NOC list :) The server must give you some kind of token that the client must store on the filesystem. It is no longer in your hands from the server perspective though. –  maple_shaft Jun 5 '13 at 9:27
    
@maple_shaft why was anyone surprised that you could do that to dropbox then? (I linked it in my question.) –  Jay Simon Jun 5 '13 at 9:40

Amazon (and many others) use a hybrid approach. They provide autologin for browsing, adding items to the cart, and placing orders using credit cared/shipping address combinations you have used before. However, they require you to enter your password for many actions such as adding credit cards, adding/changing shipping addresses, updating passwords, viewing past orders(optionally to the user), and lots of other account settings.

So yeah, people who gain access to your computer could hijack your session, but you still get what they order! (More importantly, the incentive to hijack a session is pretty much negated.) But if someone has access to my computer, I have bigger problems than people stealing the average site sessions.

If you have parts of your application that don't need as high of security, you can choose a hybrid model where you store a session ID (hashed or whatever if you'd like) to auto login users to low security portions of the site, but require them to enter the password when the enter higher security areas and delete the high security token when the session ends.

Of course if this is a banking level site, than auto login isn't an option. Again, sites that use these types of security assume the value of the data they are protecting and the added convenience to the user out weigh the potential risk of a hijacked session. If you feel that is not the case for your application, then don't implement auto logins. You need to access what level of security/usability trade offs are appropriate for your use case.

share|improve this answer

You can only if you trust the device where you store it. It is up to the user (if you can't influence the device) how secure it is. It is simply out of your hands.

As stated in the comments:

It is about what you trust. If you don't trust the machine store the ID then that is your issue. If you trust the keychain then that is the maximum security you will get. Off course you could add some custom safety like detecting device hardware or something but it's all fake-able so you cannot know in the end. It is out of your control.

share|improve this answer

Your Answer

 
discard

By posting your answer, you agree to the privacy policy and terms of service.

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