PHP Login System: Remember Me (Persistent Cookie)

How to securely implement the Remember me button in PHP (persistent login)

Can an attacker change the value of the $_SESSION['adminId']? For example, change from 1, to 12 and, therefore, login in as a different admin?

No. The session data is stored only on the server. The client only has the string which identifies the session.

I should use cookies for persistent login right?

If you're going to have persistent logins, this is usually how it's done.

so the first thing is to never store the user id in a cookie and use that to check for the log in because an attacker can easily change that right?

Correct, you will never want to expose any critical data such as a user id.

1) What should the selector and validator contain?

Each would be a properly generated random string (e.g. using openssl_random_pseudo_bytes). The selector must be unique.

2) Why is this system secure and how it prevents timing leaks?

It adds two security features over generating one basic token and looking that up directly.

First, if your database is leaked to an attacker they can not generate their own remember me cookies and impersonate every user. The validator is only stored in the database as a hashed value. The cookie must contain the unhashed value. Reversing a good hash is extremely time consuming.

Second, comparing a hash only generated on the server avoids timing attacks. If an attacker were to send various remember me cookie values to time their lookup, it wouldn't expose anything useful because the comparison on the server is against a hashed value and not the original.

Generally speaking, if your system's security is that important I would recommend against supporting a remember me feature at all. If you do want to use this feature on a important site, use a library which has already been tested to be secure.

Login 'Remember me' Cookie - Best security practices

You've got the mechanisms down in order for you to store the cookies based on user login status to the db. I would still do a checklist to be completely sure that it's secured:

Limit the amount of sensitive information stored in the cookie.

** this is ok, you're only storing Identifier and Token information

Limit the subdomains and paths to prevent interception by another application.

Enforce SSL so the cookie isn’t sent in cleartext.

** if you don't already have ssl, which is a good idea to have, you can enable ssl to send that information encrypted (you have to do that in your web server config). you can issue yourself (self-signed) ssl certificate, it won't be insured but at least the information would go in or transfer as encrypted.  

Make the cookie HttpOnly so its not accessible to javascript.

You can implement is by looking at a previous stackoverflow post: How do you set up use HttpOnly cookies in PHP

What's a secure way to create a remember me system in PHP with cookies?

I would recommend using a separate table to store saved login sessions. This table will store a unique hash generated at the time of user choosing to "remember me", the user's IP address, and their user_id.

When or If a user decides to keep a persistent login, you will generate the hash, save that hash as a cookie value, and store their IP / user_id in the "remembered" table.

In your session_start/check sequence, first check if session is set -- if not, check if cookie is set - if cookie is set, match their IP address to the cookie's hash value against the database and then if all checks out, set their session status as "authenticated".

The reason for having a table using their IP address and a unique hash is to allow multiple devices/computers to be persistent. Each device would have an entry in your remembered_sessions table.

This method does not store any passwords in a cookie, and only those who have successfully entered their password will have this cookie on their computer. Additionally even if someone grabbed that user's hash in their cookie they would need to be on the same network to be considered authenticated.

Implementing a remember me feature

Set a cookie at the same time you're setting the $_SESSION['user_id'] for instance. Like this :

$token = hash('md5',$_SESSION['user_id'] . time() . 'salt');
setcookie('token', $token, time() + (3600 * 24 * 30));
setcookie('user_id', $_SESSION['user_id'], time() + (3600 * 24 * 30)); // Cookie expires in 30 days

Save $token in DB in user_id row.

Then you set the $_SESSION['user_id'] for users with cookies saved so they don't have to sign in the normal way:

if (!isset($_SESSION['user_id']) {

if (isset($_COOKIE['user_id']) && isset($_COOKIE['token']) {

$saved_token = SELECT token FROM users table WHERE userID = $_COOKIE['user_id'];
if ($_COOKIE['token'] == $saved_token) {
$_SESSION['user_id'] = $_COOKIE['user_id'];
} else log out
}
} else log out
}
}

Maybe that works better security wise?

PHP persistent login - Do i reissue a cookie after every page authentication?

I'd vote for the second option. If nothing else, continually updating the auth cookie is a performance hit. (small but still unnecessary). At successful login, write the cookie. Once the user is in the site use only the session values.



Related Topics



Leave a reply



Submit