Is it safe to store (hashed) passwords in a cookie? - security

I've read some articles and questions on SO (e.g. here) that say you shouldn't store a user's password in a cookie. If the password is salted and hashed, why is this insecure?
In particular, why is it less secure than using sessions, the alternative usually suggested? If the user wants to stay logged in then surely this new cookie (with a session ID/hash) is exactly as secure as the one with the user's password? If the cookie is "stolen" on some way the attacker can log in as the user in the same way.
EDIT: The main crux of the question is the part about the user staying logged in, i.e. via a "Remember Me?" checkbox. In this case, surely there is only ever one session?

By putting the hashed password + salt in the cookie, you:
Open up an unlimited bruteforce vector
Allow the cookie to be copied and used by anyone (it always lets access; whereas a session does so for a period of time).
Make it harder to change hashing schemes, if it becomes relevant
Further, you generally need to store something else, to identify the user (like their user id, so you can look up their password and match it). This may lead other obscure problems.
So you're best just going with the session id approach.

Among other distinctions, if a session is stored, you own this one session. If a pwd is taken, you own every session of that user from now on.

Sessions are usually keyed to IP addresses at some level somewhat preventing session theft.
Beyond that, the session ID doesn't contain any personal information; your password, even salted and hashed does. Passwords, salted and hashed as they may be, can be reused; session ID's can't. Once the session is over, it's over, you need a new session ID to be able to impersonate the user again.

How about letting someone else deal with and think about all these issues for you? That is, use OpenID, Windows Live ID, Facebook Connect, etc.

Related

Is storing a permanent access token as good as storing password?

If I want to persist the users' login such that they do not have to re-login even after, say 1 year of inactivity, then is storing a permanent access token as good as storing the password directly (perhaps hashed), since the (permanent) access token would essentially be the "alternative password"?
Storing an access token is surely safer than storing the password directly, but let's see why:
An attacker can only get this token, but not the original password. This is better, because passwords are often reused on other sites, and/or can reveal password schemes. ➽ Make sure the token is random and not derrived from the password.
The token is not just another password. While passwords choosen by a user are often weak, a token is very strong. They are so strong, that brute-forcing is impractical. ➽ Generate random, long enough tokens, they should be at least 20 characters a-z,A-Z,0-9.
Generally speaking, yes. But, with a lot of caveats.
A long, random token, generated by a CSPRNG (this is very important, there are different ways to generate "random" strings and not all of them are really random), is stronger than a password - yes. However, the way you intend to use this token means that it is effectively a password by itself, and that means the same criteria applies:
It can't be permanent.
A key property of passwords is that they are not constants and users can change their passwords when stolen, or otherwise over time. Any kind of token should be no different, except that it should be automatically changed (rotated) by your application, on regular intervals.
It MUST be hashed!
(with a strong algorithm: bcrypt, scrypt, Argon-2I, PBKDF2; anything else is plain wrong)
Don't ever store user passwords in plain-text format, anywhere. Even if it is guaranteed that the user doesn't use this password on any other site, a plain-text password means that anybody who gets their hands on the database (even for a brief time), can hijack user accounts.
You have a responsibility to protect your users not only from "hackers", but from yourself as well.
Don't store it in a cookie, even if hashed or encrypted.
The way you've worded the question implies that you would do something like this. Cookies are not a secure location to store passwords of any kind. Temporary, short-lived tokens - sure, but not passwords.
It looks like you're trying to design your own authentication protocol, which is not an easy thing to do. It may be easy to make it work, but that's about 5% of the job; there's just too many details to consider. And all of this, for the tiny benefit of saving the minor inconvenience of a user typing-in their password once in a while - people are used to this; it's not worth the security risks.
In case you are hell-bent on providing long-lived logins, I would recommend using an existing authentication protocol. Every such protocol uses on cryptographic signatures, avoiding reliance on user passwords altogether and thus eliminating all of the above problems almost entirely.
Personally, I would just allow the so-called "social logins" - via Facebook, Google, Twitter. You wouldn't have to handle passwords at all, and anybody can login with a single click of a button.
Is better to store an access token than storing the password or the hashed password (can always try brute force to find the password) and I think you should give a token a lifetime.
Although the answer is yes, but it also depends on the place you are storing the token. And you might want to auth the user with XSRF/CSRF token as well along with the token.
But storing token is better than storing password.

Why should I use session id in cookie instead of storing login and (hashed) password in cookie?

(I was surprised that this question wasn't asked on Stack for now, but I've done some searching and couldn't find anything o.O)
I am working on service-based webapp and I wonder what is the best way for handling user logins. So far I have:
When user login in, they supply creditials. Password is salted and hashed locally, than it's transmit to server over POST (so sniffing users won't be able to retrieve original password ie. to check them on the other sites)
Login and hashed password are stored in cookie with TTL of 15 minutes (revoked every single webaction)
Passwod is server-side salted and hashed again, and than it's compared with password stored in database (so, passwords are double hashed with different salts, this is for someone who'll break into database - they still won't be able to recover login creditionals)
User can do at most 3 login attempts per 5 minutes from single IP
Users get information about last successful and unsuccessful login attempts alongside with date and IP
Someone had noted that it's better to store unique session id instead of hashed password in cookie and I wonder why it is so important - if someone sniff packets, than it's no matter session id or not - they still can get packet from login with all data needed to pose as legitimate users and login themselves. So are there any other advantages of stored session-id approach over storing login and hashed-password in cookie appraoach?
Storing the hashed password as a cookie is very nasty vulnerability and is an OWASP Violation. The whole point in hashing a password is you are forcing the attacker to break the hash in order to login. If the attacker can just pull the hash from the database and then login, then you have a system that is equivalent to storing password in plain text.
Every platform has a session handler, in php just use session_start() and the $_SESSION super global. By writing your own session handler you will be less secure.
By storing a session ID you can identify different sessions of the same user, and you may want to handle them in any special way (e.g. just allow a single session, or have data that's associated with the session instead of to the user).
And you can distinguish easly activity from different sessions, so you can kill a session without having to change your password if you left it open in a computer, and the other sessions won't notice a difference.
Double hashing doesn't protect you from the exploit.
If one takes the stored user id and hashed password from the cookie and send to the server, he would instantly gain access.
With session ids, it would at least time out.

Is it really dangerous to save hashed password in cookies?

There are many discussions about security risk for saving hash password in cookies, as upon accessing to the user's computer, a hacker can log in with the saved password. If a hacker has access to the user's computer, he can catch the password, as browsers also save passwords locally (encrypted of course). What is the difference between password set in cookies with that saved by the browser?
For obvious reason, a temporary GUID should be send instead of password. In any case, I believe that limiting access to the logged IP can close doors for attackers to use locally saved GUID. Of course, it will limit the length of logged period, as IP is usually dynamic and regularly changes; but I think it is worth of its noticeable security. Any idea?
I suppose the reason why you would want to store a hashed password in a cookie is to create a "remember me" cookie. So you need a value for the cookie that is secret, so that not someone else could easily guess it. Anyone with access to this value would be able to log in as this user, so it is actually an "extra password".
There are two risks involved here:
Most important is the risk of exposing the password. This would not only put your site at risk, but potentially other sites as well. Most users re-use their password for everything, and the password would probably give an intruder access to both the users email account and netbank. Someone with access to the hashed value may use brute force or rainbow tables to discover the original password (rainbow tables are long lists of pre-calculated hashes). Rainbow tables are easily available for passwords up to more than 8 characters, and even longer. You may avoid this by salting the password so that it is i.e. more than 20 characters before you create the hash (remember to store the salt in the cookie as well). A properly salted password hash calculated with a safe hashing algorithm should be quite safe.
The other risk is connected to the fact that the user must change his original password to make the hashed password string invalid. It is impossible for the user to actually turn off this feature once it is turned on. You may delete the cookie when he un-checks the "remember me" button, but that will have no effect if the cookie already is compromised. What if his computer is i.e. stolen? If the user has checked this button on one computer then he must have access to that computer to disable this feature.
Yes, it's less secure to use the hashed password in a cookie. There is a difference between saving it in the browser and sending it over the wire: unless you're always using SSL, an attacker doesn't need access to the machine to read the cookie out of the request.
It's much safer to send a random value, as then there's no tie to the user's actual password: it's possible to expire a session by forgetting the random value, without having to get the user to change their password. Also if the attacker does get the hashed value out of the cookie, it may be possible for them to recover the actual password if that's what's sent.
as upon accessing to the user's computer, a hacker can log in with the
saved password. If a hacker has access to the user's computer, he can
catch the password, as browsers also save passwords locally (encrypted
of course).
Not sure what you mean here. If you ask IE to remember your password for a site and someone has the password to your computer and can use your IE then yes, he can log-in using your password. But this is not related to hashing or cookies etc.
First of all, a hashed password can not be retrieved. So if someone has the hash of your password, he does not know your password.
When you login to a site that requests a password, you provide the password which is send encrypted. The standard practice is to store the user's password as a hash i.e. not the password itself. So you type the password and the receiving server will compare the hash with the one stored.
Now related to your question on sending the hashed password inside a cookie, this is related to session management. I.e. to determine whether a user has already succesully loggedin or not.
IMHO using just the hashed-password as a way to determine if the user has already logged-in when using plain HTTP is not a good idea.
But if this what you ask, it is another topic.
I.e. how to best do session management over HTTP connections
Times when you should ask the user to re-enter their password:
When they try to change their password.
When they try to change their email address.
When they try to change their security information (anything that can be used to recover their password, including username, email address, security question, etc.).
When they try to access highly secure account information and have not entered their password for more than 15 minutes or so (if all information is highly secure, you should flat out log them out for inactivity instead). Amazon does this a lot.
Saving a hashed password makes this less effective.
As an aside, you should already be using cookies that are Secure (won't transmit over HTTP), HttpOnly (not accessible via javascript) to protect against XSS attacks. Of course, if someone hacks the person's machine completely they'll just install a keylogger.

Is permanent session / 2nd password a good idea?

So, the idea is to store for each user another "password" or auth value, when auth via cookies you just compare the values. That way if the cookie is somehow stolen is has nothing to do with the real password.
For important operations, like changing password etc the user needs to provide his password and its validated vs the original password (salted, encrypted etc).
IMO there is no reason for the password and the session/auto-login-cookie to be related in any way. So yes, I'd make them completely separate. I usually use a random value in the cookie and associate server side data with it. This also allows me to invalidate any cookie from the server side.
Your question is not really clear, but do NOT put the password in your cookies.
That way you just need one password anyway.
One solution with "permanent" cookies is to have a time limit to the session and if that limit is reached, the password is required to do important things (i.e. access your account, see your email, change password, etc.)
As mentioned by CodesInChaos, the cookie is just a random number. However, you have to make sure that the number is generated by a good random generator (i.e. some OpenSSL function that says it has very good entropy).

Is it advisable to store a hashed password in a cookie?

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
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).
Here is an excellent article on this very topic. Many of the answers to your question are hitting on techniques outlined in it.
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.
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.
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.
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.

Resources