Page 1 of 1
Login Remember Me
Posted: Wed Aug 24, 2011 7:49 am
by lenton
Hello, I am creating a 'remember me' feature for my login which allows the user to only have to login once.
At the moment I store the username and password in a cookie, the password is encrypted with MD5 but that's hardly secure. Anyone could view the cookie and obtain their username and password.
How can I make this more secure? I did read somewhere about storing a session ID as a cookie instead?
Re: Login Remember Me
Posted: Wed Aug 24, 2011 10:27 am
by s.dot
I believe some simply extend the login cookie.
In the past I have generated a random string, and hashed the sum of login + password + random string and stored it in a cookie, while storing the random string in their users database row.
Then, upon a page view, if not logged in, i'd check for the cookie hash string, and compare it to a recomputed hash of login, password, + random string from their database row. If it matches I log them in automatically and generate a new random string and re-set the cookie.
Re: Login Remember Me
Posted: Wed Aug 24, 2011 11:44 am
by lenton
I don't understand what you're saying, would doing that stop people from using the cookies if they were stolen from a users computer?
Re: Login Remember Me
Posted: Wed Aug 24, 2011 11:48 am
by Jonah Bron
s.dot! Haven't seen you around in a while.
@lenten: nothing, and as far as I know, there's no practical way to prevent that at all (short of requiring the user's credentials every on every page load). That's known as "session hijacking", as you may know. Is this application being designed for a demographic that is at that risk?
(old discussion about this here:
viewtopic.php?f=6&t=127262 )
Re: Login Remember Me
Posted: Wed Aug 24, 2011 12:37 pm
by s.dot
Jonah Bron wrote:s.dot! Haven't seen you around in a while.
Been super busy!
@lenten: nothing, and as far as I know, there's no practical way to prevent that at all (short of requiring the user's credentials every on every page load). That's known as "session hijacking", as you may know. Is this application being designed for a demographic that is at that risk?
There's fingerprinting, to decrease the risk.
Re: Login Remember Me
Posted: Wed Aug 24, 2011 12:54 pm
by Jonah Bron
Oh, you mean like adding the IP address to the hash? Yeah, I forgot about that.
Re: Login Remember Me
Posted: Sun Aug 28, 2011 3:42 pm
by phphelpme
Hashing the username, password and secure code together and storing in cookie would be fine because if the cookies get stolen from the computer they are on then thats not your security problem. You have secured the details within a hash etc so you have done your bit.
If the computer gets hacked and the cookies are stolen then its the users own risk to there own system and not yours. Its only like getting hacked and someone finds a file with all your username and passwords stored in there. You have to contact all your accounts and tell them etc and change the user/pass etc.
Try not to think about it too deeply as the user has to take responsibility also for their own security.
Best wishes
Re: Login Remember Me
Posted: Mon Aug 29, 2011 11:24 am
by RCA86
If it bugs you that much, just remember that the whole idea of a 'remember me' function sacrifices security for convenience. There's no real way around that, so don't beat yourself up too much. At the same time, I wouldn't say it's "up to the users", purely because if you give them the functionality, the majority will use it. So you have to decide for yourself whether the risk is worth it.
Re: Login Remember Me
Posted: Wed Aug 31, 2011 7:54 am
by phphelpme
@RCA86 I agree with your notion of deciding whether or not this feature is worth the security risk.
I personally do not and NEVER WILL use this function because if you are going out of your way to make a secure envirnment then why throw all that away by giving this silly if not LAZY option for your customers.
Lets face it, so many people are now using cleaning programs to clear cache, cookies, temp files etc so sooner or later they are going to have to login to create the cookie again.
Best wishes
Re: Login Remember Me
Posted: Wed Aug 31, 2011 9:49 am
by lenton
Ok, thanks for all your replies. I have just figured out that other websites can't access cookies that have been made in another domain. Obviously this would be a huge security risk which was why I was so worried.
The remember me feature is a must for me, I hate having to keep logging in all the time.
At the moment the password in the cookie is encrypted with MD5 which isn't that secure. Is there an encryption in PHP that can be encrypted with a password and then decrypted with the same password?
Re: Login Remember Me
Posted: Wed Aug 31, 2011 11:02 am
by phphelpme
Add a salt to the password then encrypt it. Then simply encrypt user input when logging in and compare encryptions.
Code: Select all
// this is what it normally looks like when hashing a string using md5
$password = md5($password);
// using a salt, you instead concentate a string to the password before hashing it
$password = md5($salt.$password);
and heres a basic example of how to use it:
Code: Select all
$password = "shaunellerton";
$salt = "t2H45Dfe12jiR8";
$password = md5($salt.$password);
Suppose you use the password “shaunellerton” from the example (my name (shaunellerton) which many people STILL do you know or even worse their date of birth). Then the generated hash would actually become “t2H45Dfe12jiR8shaunellerton” which is a considerably stronger password than “shaunellerton”. This takes care of the user’s bad habit of using easy passwords with only lowercase characters.
Just remember that you don’t have to use the salt in the beginning of the string, the principle is the same if you do this:
You can do it however you want and really this is the tip of the iceberg hear. You have so many different options open to you here and one common technique is mixing your hash techniques such as:
Code: Select all
$password = "shaunellerton"
$salt = sha1(md5($password));
$password = md5($salt.$password);
Its your mind thats the limit here. You can also code an auto salt generator which uses special characters and never repeats characters too. There are no limits really and the more you do the more secure but lets face it, if they have access to the cookie then it dont matter what you do.
You can always use salts in your coding and change them every month for users that are using the remember me function. This way when you change the salts the user is forced to log in again because the existing cookie wont be accepted. Wordpress uses this principle as well as other common cms systems.
If you want more advice just PM me about it if need be.
ANOTHER POINT! - Why store your password in the cookie? why not store a unique hash that gets generated when the user logs in and then store that in the cookie instead of the password. Then the password is never stored on the computer of the user. You can then check for the unique hash when a user visits the site and if it exists in a table near the username etc then they are logged in. If not then they have to log in. This would give you easy access to reset all unique hashes on all accounts for security reasons just incase someone has there cookie stolen etc.
Best wishes
Re: Login Remember Me
Posted: Sat Sep 03, 2011 10:05 pm
by s.dot
Here's a code snippet from what I used to use on one of my old sites
It doesn't look too bad but I would do it a bit differently now (mostly using more objects).
This code will check if logged in
-> if not logged in, check for autologin cookie being set
-> if cookie is set, check that the cookie hash value matches regenerated hash value from database
-> if it does, log them in
-> generate new hash, and set new cookie
The only thing I don't like about this code is it uses a unique identifier in the cookie (users id). But I was ok with that at the time because I didn't use ids for anything (database had username foreign keys).
Code: Select all
//try auto login if not logged in
if (!isLoggedIn())
{
if (!empty($_COOKIE['autologin']))
{
if (strpos($_COOKIE['autologin'], ':'))
{
$pieces = explode(':', $_COOKIE['autologin']);
$alid = mysql_real_escape_string($pieces[0]);
$alRes = mysql_query("SELECT `id`, `username`, `auto_login_string`, `dob_month`, `dob_day`, `dob_year` FROM `users` WHERE `id` = '$alid' LIMIT 1")
or die(mysql_error());
if ($alArr = mysql_fetch_assoc($alRes))
{
$hash = $pieces[0] . ':' . hash('sha256', $alArr['id'] . $alArr['auto_login_string'] . $alArr['username']);
if ($hash == $_COOKIE['autologin'])
{
//login
session_regenerate_id(true);
$_SESSION['logged_in'] = true;
$_SESSION['username'] = $alArr['username'];
$_SESSION['id'] = $alArr['id'];
$_SESSION['age'] = getAge($arr['dob_year'], $arr['dob_month'], $arr['dob_day']);
mysql_query("UPDATE `users` SET `last_active` = '" . time() . "' WHERE `username` = '" . $alArr['username'] . "' LIMIT 1")
or die(mysql_error());
//generate new key so old one can't be re-used
$key = substr(md5(microtime(true)), 0, 10);
//update key in database
mysql_query("UPDATE `users` SET `auto_login_string` = '$key' WHERE `username` = '" . $alArr['username'] . "' LIMIT 1")
or die(mysql_error());
//hash cookie value
$newHash = $alArr['id'] . ':' . hash('sha256', $alArr['id'] . $key . $alArr['username']);
//set cookie
setcookie('autologin', $newHash, time()+60*60*24*365);
}
}
}
}
} else
{
mysql_query("UPDATE `users` SET `last_active` = '" . time() . "' WHERE `username` = '" . $_SESSION['username'] . "' LIMIT 1")
or die(mysql_error());
}
Edit| And for this to work, the autologin cookie has to be set on login, too, so here's that code
Code: Select all
//auto login
if (isset($_POST['autologin']))
{
//generate key
$key = substr(md5(microtime(true)), 0, 10);
//store key in database
mysql_query("UPDATE `users` SET `auto_login_string` = '$key' WHERE `username` = '" . $arr['username'] . "' LIMIT 1")
or die(mysql_error());
//generate hashed cookie value
$hash = $arr['id'] . ':' . hash('sha256', $arr['id'] . $key . $arr['username']);
//set cookie
setcookie('autologin', $hash, time()+60*60*24*365);
} else
{
//set to blank autologin string
mysql_query("UPDATE `users` SET `auto_login_string` = '' WHERE `username` = '" . $arr['username'] . "' LIMIT 1")
or die(mysql_error());
//unset autologin cookie if it is set
if (isset($_COOKIE['autologin']))
{
setcookie('autologin', '', time()-60*60*24*365);
}
}
Really hope this helps someone! Even if it just gives ideas.
Re: Login Remember Me
Posted: Sat Oct 29, 2011 2:44 am
by uday8486
You can otherwise use combination of mcrypt module and the some id or a identifier like a date when user has logged in with the remember me option.