17

I want user's to be able to select a "remember me" box on my website so they need not log in each time they come. So, I need to store a unique ID in a cookie to identify them. Is it safe to hash their password with sha512 and a long salt in PHP and store that value in the cookie? If the cookie was stolen, would their password be at risk? Obviously it must be connected to their password somehow, otherwise if the cookie value was guessed or stolen, the user would not be able to stop someone else logging in.

Also, is it advisable to use a GUID at all as the unique identifier?

Thanks, Ben

Ben
  • 191
  • 1
  • 4

6 Answers6

22

Remember, the hash of the password is effectively the same as their password. Somebody who stole the hash would have the same access to the user's account as if they had stolen their password. Therefore it is not advisable to store a hash of the user's password in a cookie unless there was some other information not stored with the cookie that is used to authenticate (i.e. 2-factor authentication).

Gabe
  • 84,912
  • 12
  • 139
  • 238
  • +1 exactly, otherwise whats the point in even hashing the password in the first place? Its designed to delay the attacker! – rook Mar 02 '10 at 07:37
  • this of course assumes that the attacker knows what hashing algorithm is used and whether a salt is involved...still, not advisable – zzzzBov Dec 09 '10 at 22:03
  • 3
    hashed passwords are hardly to be recovered, and because many people uses the same passwords for other sites as well, that's the difference between exposing one service and exposing credentials for a lot of other pages :) – PiotrK Oct 30 '12 at 19:03
  • 2
    Not going to go as far as a downvote, but I don't agree with the "effectively the same" part. Most login mechanisms such as form-based authentication is going to require a plain-text version of the password (sent over SSL of course) to actually login, not a hashed version of it. Granted, if they know the hash algorythm they could use a brute force method to work backwards and create a PW fairly quickly. However, if you created the hash server-side, then hopefully server code is secure and they don't know the salt. Also, PiotrK has a good point. – eselk Feb 12 '13 at 20:26
  • 1
    @eselk: I'm not sure you understood the question. The OP is wondering if it's secure to store the password hash in a cookie and use that to authenticate. If he does that, the hash just becomes a complicated plaintext password. An attacker who gets the hash *wouldn't have to* work backwards to get the password, because they wouldn't need it. – Gabe Feb 12 '13 at 20:35
12

Here is an excellent article on this very topic. Many of the answers to your question are hitting on techniques outlined in it.

Chris
  • 1,826
  • 12
  • 15
4

There's a low risk with a good algorithm and large salt, but why take any unnecessary risk?

If you just need to identify the user, then store something that can uniquely identify the user, like a guid along with some other stored verification code (not their password, some random long string). I wouldn't use a guid alone as it would not be a safe method of authentication.

Samuel Neff
  • 73,278
  • 17
  • 138
  • 182
  • It is advisable to delete or modify this "random long string" when/if the password is changed, lest the user (or someone with the said cookie) were to present such a cookie some time after the password was changed (or the user de-selected the remember me, or...) – mjv Mar 02 '10 at 04:24
  • 4
    The "random long string" should expire much more often than when the password changes, ideally at every login. – Matthew Flaschen Mar 02 '10 at 04:28
  • 1
    The string points to a user. It has nothing to do with authentication. You can delete it whenever you want to expire cached credentials, which is not really related to changing the password. – Samuel Neff Mar 02 '10 at 04:29
  • @Sam agreed; _technically_ the cached _identification_ is unrelated to the current value of the password. However, a bit like when someone changes the lock on their home's door, he/she expects that any other mean of entry (like a hidden key under the map, even if such analogy if flawed) will be so voided. Such expectation carries into the virtual world, and that's why it is probably a good practice to void the cached id. – mjv Mar 02 '10 at 04:37
  • 1
    @sam, -1 leaking the password hash is ALWAYS a vulnerability. – rook Mar 02 '10 at 07:36
  • Thanks! Wouldn't re-creating the random number on every login log a user out of one computer if they logged in on another? So a safe method of authentication, seems to be to generate a random set of characters, say 256 bits, and append that to their userid and check that. When they log out or change their password, it clears or creates a new random string. – Ben Mar 02 '10 at 13:32
  • @Rook, that's pretty picky, but whatever. – Samuel Neff Sep 13 '12 at 13:06
  • @Samuel Neff I am glad you changed your post. But seriously this is a recognized vulnerability and CVE's have been issued for it: http://cwe.mitre.org/data/definitions/319.html – rook Sep 13 '12 at 20:25
  • @Rook, I didn't change my post. I'm meant it's being picky because I am recommending they don't store the hash, but perhaps my language wasn't quite strong enough for your taste. Besides, the CVE you cited is in reference to leaked MD5 and "weak" (unspecified) hashes. Use bcrypt and it's much stronger. Still best not to expose it, as I said in my post. – Samuel Neff Sep 14 '12 at 04:39
  • @Samuel Neff Such disregard for security is horrific. Please don't spread these ideas. – rook Sep 14 '12 at 05:10
  • @Rook, did you read my answer? I said don't store the hashcode, store some random verification code. – Samuel Neff Sep 14 '12 at 19:56
2

It wouldn't hurt to have some kind of "password" in the cookie along with a user id (to prevent users from changing the uid to that of another user), just don't make the "password" the same as the actual user's password.

And just because it's a hash doesn't necessarily mean it's one-way (well, by definition it does, but there are utilities to generate MD5 plaintexts and I would guess it's only a matter of time before it happens to others). I would hash some kind of secondary password.

Adam
  • 647
  • 2
  • 8
  • 19
2

An alternative way of doing this might be use the cookie as an encrypted storage for only indirection data. You'd need some sort of unencrypted identifier that would serve as a pointer to the key (or the required information to derive the key) in the application's database, followed by a blob encrypted by the key obtained from the identifier, which itself would contain some sort of one-time-usable identifier that authenticates the session.

Given the following assumptions:

  • Your database is secure (e.g., your application can access it, but your user cannot directly do so, and also assuming that the application has been proofed against SQL injection)
  • Your salts are strong; that is, reasonably high-entropy enough that attempting to crack the salted password is infeasible even if the password is known

Then what this would provide is a method by which one can be reasonably certain that the session is not able to be hijacked or stolen in any way. That is to say that a copied cookie is only of limited usefulness, since the user must not have used the cookie between its theft and usage by an attacker.

While this protects against replay, it also means that if someone does manage to steal the cookie at exactly the right time, and manages also to use it before the original, legitimate user does, the attacker now is in control of the session. One can limit a session to an IP address to mitigate that risk (somewhat; if both the user and the attacker are behind the same NAT, which is the most likely scenario in any home or small-to-medium business network) then this point is pretty moot, since the IP address would appear to be the same anyway. Also useful might be limiting to the current user agent (though that can break unexpectedly if the user updates their browser and the session does not expire at browser close time), or finding some method by which one can identify the computer that the user is on just well enough that there is reasonable certainty that the user hasn't moved the cookie from one system to the next. Short of using some binary plugin (Flash, or Silver/Moonlight), I'm not sure that the latter is possible.

To protect against a permanent session hijacking, require that the user to reauthenticate him- or herself periodically (e.g., limit the allowed session lifetime or require something like a token/fob/dongle) and require that the user reauthenticates him- or herself upon entering sensitive areas of the application, such as password change and potentially dangerous actions, patterns or behaviors such as the deletion of data, unusual usage patterns, bulk actions, and so forth.

It is difficult to secure applications and yet retain their ease-of-use. If done carefully, security can be implemented in a manner which is minimally intrusive and yet still effective—well, for most Internet-facing applications, anyway.

Michael Trausch
  • 3,187
  • 1
  • 21
  • 29
1

It's not advisable, but if your gonna do it, at least salt your passwords before you do so. This will stop people from using hash crackers if they do manage to get hold of your visitor's cookies.

carlos
  • 11
  • 1