I was wondering what the safest way of a cookie login is? If you just store the pass(encrypted with salt) and username in the cookie and validate it against the user table, a potential attacker can steal a cookie and login. People normally don't check there 'last time online'.
So is there a better way for the 'remember me cookie'? IP isn't a good option, is it? (Some machines change IP all the time).
You can ensure that cookies are sent securely and aren't accessed by unintended parties or scripts in one of two ways: with the Secure attribute and the HttpOnly attribute. A cookie with the Secure attribute is only sent to the server with an encrypted request over the HTTPS protocol.
Persistent cookies are implemented by many websites as a "remember me" checkbox on the login page; when selected, a persistent cookie is sent to the client browser upon login. The user authentication cookie model gives users the convenience of not having to enter login credentials every time a site is revisited.
The cookie will only be added to connections such as HTTPS (HTTP over Transport Layer Security (TLS)). Note that it is up to the browser to decide what it considers 'secure'. Typically the browser considers it secure if the protocol makes use of the secure-transport-layer.
Cookies are sent within the HTTP header. Thus they are as secure as the HTTPS connection which depends on a lot of SSL/TLS parameters like cipher strength or length of the public key. Please keep in mind that unless you set the Secure flag for your Cookie, the Cookie can be transmitted over an unsecure HTTP connection.
I think I've found a clever solution!
Advantages of this (complicated?) script:
I've made a table in the database with the following information:
session | token | username | expire
The remember me cookie will have this setup:
$value = "$session|$token|$userhash"; //Total length = 106
Session
will be a string of 40 (sha1)
characters.Token
will be a string of 32 (md5)
characters.Userhash
in the cookie will be a
string of 32 (md5 of username)
characters.Username
in the database will be the
normal username.Expire
will be now + 60 days.The script:
if(isset($_SESSION['check']) || $_SESSION['check']){
//User is logged in
}else if(isset($_COOKIE['remember']) && strlen($_COOKIE['remember'])==106){
//THERE is a cookie, which is the right length 40session+32token+32user+2'|'
//Now lets go check it...
conncectdb(); //Sets connection
//How do I protect this script form harmful user input?
$plode = explode('|',$_COOKIE['remember']);
$session = mysql_real_escape_string($plode[0]);
$token = mysql_real_escape_string($plode[1]);
$userhash = mysql_real_escape_string($plode[2]);
$result = mysql_query(" SELECT user
FROM tokens
WHERE session = '$session'
AND token = '$token'
AND md5(user) = '$userhash';")
if(mysql_num_rows($result)==1){
//COOKIE is completely valid!
//Make a new cookie with the same session and another token.
$newusername = mysql_result($result,0,0);
$newsession = $session;
$newtoken = md5(uniqid(rand(), true));
$newuserhash = md5($username);
$value = "$newsession|$newtoken|$newuserhash";
$expire = time()+4184000;
setcookie('remember', $value, $expire, '/', 'www.example.com', isset($_SERVER["HTTPS"]), true);
mysql_query(" UPDATE tokens
SET token='$newtoken', expire='$expire'
WHERE session = '$session'
AND token = '$token'
AND md5(user)='$userhash';");
//Set-up the whole session (with user details from database) etc...
} else if(mysql_num_rows(mysql_query("SELECT user FROM tokens WHERE session = '$session' AND md5(user) = '$userhash';"))==1)){
//TOKEN is different, session is valid
//This user is probably under attack
//Put up a warning, and let the user re-validate (login)
//Remove the whole session (also the other sessions from this user?)
} else {
//Cookie expired in database? Unlikely...
//Invalid in what way?
}
} else {
//No cookie, rest of the script
}
Advantages of the script:
Reference: http://jaspan.com/improved_persistent_login_cookie_best_practice
Such a “remember me” feature is always an additional security risk.
Because just like in a session you only have one identifier that suffices not just to identify a user (Who is it?) but also to authenticate that user (Is it really him/her?) without doing an actual authentication.
But in opposite to a session that has (or should have) just a short life time (mostly less than an hour) and the identifier is (or should be) changed periodically (time based and on necessity due to authenticity/authority state changes), a “remember me” identifier is valid for days if not even for months or years! And this long validity period poses an additional security risk.
So before asking how to implement such a “remember me” feature, you should ask yourself if you really want that additional security risk. That mainly depends on the assets that your application has and what purpose the authentication has and if you want to take the risk of impersonations/identity thefts that the “remember me” feature poses.
If so, make sure to provide basic security by using HTTPS and set the HTTPOnly flag and the secure flag in your cookies. Then you could do the following to build such a “remember me” feature:
Authentication request
If the user authenticated via HTTPS and set the “remember me” option, generate a random remember me token, store it on the server side in a “remember me” database, and set the remember me cookie with the secure flag with that value. Then start a new session and set a remember me flag.
Any other request
With this the authentication is secured via HTTPS, both the initial authentication and the “remember me” authentication. And the user is only authentic during the current session; if it expires, the user has to re-authenticate either by using the remember me token or providing his/her login credentials. And as the remember me tokens are stored in the database, the user can invalidate any existing remember me token.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With