18

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).

7
  • 2
    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. Jun 5, 2013 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, 2013 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. Jun 5, 2013 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, 2013 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. Jun 5, 2013 at 9:06

4 Answers 4

13

One 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, use HTTPS for increased security, obviously.

Update 2: Note that this approach has limitations, in that it doesn't work well for users who change their IP address a lot. However, it does provide an increased level of security and may be useful in some situations.

5
  • 1
    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, 2013 at 9:16
  • 2
    @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.
    – user82096
    Jun 5, 2013 at 9:22
  • 3
    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, 2013 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.
    – user82096
    Jun 5, 2013 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, 2013 at 20:06
6

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.

2

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.

6
  • 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, 2013 at 9:07
  • how are you going to get the key? it's stored locally on someone's computer.
    – Ryan
    Jun 5, 2013 at 9:11
  • you walk up to the computer and open the file where it's stored :)
    – Jay Simon
    Jun 5, 2013 at 9:14
  • 2
    @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, 2013 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, 2013 at 9:40
0

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.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge that you have read and understand our privacy policy and code of conduct.

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