Is permanent session / 2nd password a good idea? - security

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

Related

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.

HTTP Remember me authentication

I'm trying to write a simple HTTP remember me authentication system for users.
My users could be represented as such
{
"email" : "foo#bar.com",
"password" : "8EC41F4334C1B9615F930270A4F8BBC2F5A2FCD3" // sha1 hash of password
}
So my idea is that I need to create a cookie, with indefinite (really long) expiration time, that will hold some type of information to enable me to fetch the user from the database, therefore logging the user in.
My first idea was to just simply store the email:password string as a cookie. I thought this would be good since nobody else can really generate that type of information other than the user itself, and I could retrieve the user quite easily by simply comparing the username and password based on what's in the database.
However then I thought this wasn't really good. It turns the password digest into, effectively, a second password that's stored in the clear and passed over the wire in every request.
So then I thought maybe I could generate a signature each time the user logs in, which would basically be a random hash that is stored directly in the user object in the database.
The user logs in, it generates this signature that is stored, and the cookie holds this signature. Whenever you access the website, the site checks which user has that particular signature and logs the user in. Logging out will effectively erase the cookie, and new logins will generate a new random signature.
Does this approach take into account any other vulnerabilities?
I know, I should probably use a library already made for this, but this is just simply an exercise in web-security.
This is essentially what most sites do when you log in. Yes, the cookie should hold a unique identifier for the user's "session". The cookie should be essentially random. Up to you whether to make it persistent across browser sessions.
Along with the cookie in your authentication DB, also store a timestamp of when the entry was created. Cookies older than N seconds should be considered invalid (set N to your taste). You can reset the timestamp each time the cookie is used so that idle sessions time out.
Note that the same user may want to have multiple sessions (do you ever log in to your Email account from both home and work?), so the concept here really is "session", not user.
Vulnerability point-of-view both are same! Cookie stealing and related mechanisms however browsers are smart enough now so you shouldn't worry about that.
Second approach is good in terms of privacy as well since it does not includes email address in the cookie. And it seems much more similar to like storing the sessionID which in your case you are generating a random hash and storing it in DB.
But i think it would be more wiser to use the first approach; you can add another layer to the digest and encrypt it with your some algo or private key; to be on safer side.

Would this cookie system be secure for storeing passwords?

I'd like input on this cookie password storing security system,
When the user ticks the remember me box, it stores these cookies:
User name in plain text.
Password encrypted with a completely random key that the server stores in the database, that is never passed to the client and is user-specific, changes with every login.
And the server then decodes the password with the encryption key when needed.
An attacker could steal somebody else's cookie and then be logged in without having to know the actual password. They would just send the same cookie and would get in. Being able to sniff traffic off the wire and then resend it later is a replay attack.
The best defense is to use SSL so the security is end to end. If you're running a serious commercial site then you should use SSL, no ifs ands or buts. Using SSL cookies will always be encrypted over the wire so it doesn't matter quite so much what their contents are as the attack vector changes from packet-sniffing to having to read the cookie off end users' hard drives.
If your site is not quite so serious, then read on.
On my site, I take the user's password and concatenate their IP address plus a secret token and hash all of those. That hash is stored in a cookie. Then to authenticate them on the server I recalculate the hash and verify that the one they sent matches.
This ties the cookie to a particular IP address so it cannot be so easily reused by a third party. It also eliminates any danger of decrypting the cookie and discovering the password since the hash (SHA256, say) is one-way and cannot be reversed.
Also, I hope you are not storing raw plaintext passwords on your database. You are storing password hashes, yes? And are also salting them to prevent rainbow table attacks?
No offence intended, but why do you want to reinvent the wheel?
Many have already implemented their own versions of this particular wheel so why not search SourceForge? Reusable software - can you code this more quickly than you can find an acceptable (and tested) solution?
Use off the shelf building blocks for the grunt work and move on to the interesting parts ;-)
Per #caf, adding this as an answer:
If you're going to go down this path, where the cookie basically stores the server's secret, there's absolutely no reason for that secret to have anything to do with the user's password. The client can't interpret the meaning/value of that data anyway.
To the client, it's just random data since it doesn't know the key
To the server, it's no different from any other data that is
Unique to the client, and
Secret to the server
To an attacker, it's neither more, nor less random (or similarly, hard to brute-force) than a random number of equal bit length.
In essence, that encrypted data is just an authentication token with special rules for how the token was generated. But making the token the user's encrypted password only adds more risk, because now if an attacker somehow gets the encryption/decryption key from the server, they have your user's password. You've made the token itself an attractive target since it has intrinsic value.
So instead of storing the encrypted password in the cookie and the encryption key in the database, you could just have the server generate a sufficiently long random number and store it in both the DB and the cookie. Since it has no meaning to the client anyway, it doesn't really matter what you use for the token, as long it's random, hard to guess and the server can verify it. Don't bother making it have a correlation with the password.
As Leonix said, this is probably better left to someone else who has developed it before and fixed all the bugs. Especially because it's security related.
Other than that, a glaring flaw I can spot is lack of authentication, or susceptibility to a 'replay' attack, where someone just blindly sends the cookie data that they could of copied from whom they want to impersonate.

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.

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

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.

Resources