I would like for my users to have the capability of "Keep me logged in" when they log in to my website. At the suggestion of the top answer on this post, "Keep Me Logged In" - the best approach, I decided to hash a combination of the user's salt and password in one cookie and store the user's id (a number) in another cookie. Of course, the hash value will also be stored on a database server-side to be validated when the user returns again. The salt value I used is the same one that I used to hash the password of the user when they first register, so it is static - it doesn't change between sessions. There's a few of problems I see with this approach.
1) Is using the registration salt a good idea if it's static or should I generate a different salt each time for the cookie?
2) If someone were to gain access to the cookies and they copy them to a different computer, and then try accessing the website from that computer, theoretically, it will automatically log them in to that user's account, is this not a security issue?
3) In a scenario where some user with malicious intents were to gain access to the database, a secure website would have salted and hashed passwords making it rather difficult for the hacker to gain access into multiple accounts (if at all). But, by simply playing around with the hash and salt values and creating a cookie that matches the values they've changed on the database, they can effectively get access to any account they want, rendering the whole password-hashing process as useless. Therefore, this cookie approach I'm using now is compromising my entire database and all my users' accounts.
So my question is, how do I store a cookie in PHP with sensitive information such as a hash of the user's password without having to worry about the aforementioned issues? Surely websites like Gmail and Hotmail, who offer this "Keep me logged in" feature follow a more secure approach than what I'm doing now, so how would they do it?
Don't store the password in the cookie, hashed or not. In fact, there's no reason to store anything sensitive in the cookie. All you need to do is map a 128-bit (or larger) random id to a user account in your database, and store that id in the cookie. There is no way somebody is going to guess a valid id by remote brute force, especially if you have lock-outs in place.
Yes. That's the downside to the feature. However, if your website detects new IP address (particularly from different countries) and requires a second step (text a code to a mobile device, etc), then you take care of this problem along with the general problem of a stolen password. (This of course doesn't help prevent local network attacks, like an insecure public wifi.)
A more convenient solution is to require the "remember me" cookie to use SSL. That way a hacker would not ever see the cookie in plain text transmission, and a local attack would probably be required. (And if such, the remember me cookie is probably the least of the user's concerns.)
Yes, and no. If you use the technique I described (random id) then they can only access accounts that have a "remember me" cookie. But that said, if they have access to your database, they can brute force any account they want. Even salted passwords are easy to crack locally if the password itself is weak.
Also, you can consider the "remember me" login to be a half-login. Access to purchase something, change an email address, etc, would still require a password to be entered. Doing harmless things like posting on a message board could be done without the password.
Finally, note that a PHP session cookie is nothing more than a temporary "remember me" token! So much of this applies to the concept of session hijacking. The "remember me" token simply adds a bigger window of opportunity.
So in short: don't store anything sensitive in the cookie, require SSL for the cookie, and if possible, implement multi-factor authentication ... especially for admin accounts.