什么是使用登录cookie的相对安全的方式? [英] What is a relatively secure way of using a login cookie?
问题描述
我想知道什么是最安全的cookie登录方式?
如果你只是把pass(用salt加密)和用户名存储在cookie
中并对用户表进行验证,一个潜在的攻击者可以窃取cookie并登录。
人们通常不会在最后一次在线检查。
那么记住我cookie有更好的方法吗?
IP不是一个好的选择,是吗?
我认为我找到了一个聪明的解决方案!
这个(复杂的)脚本的优点:
- 当用户成功登录
用记住我选中,除了
标准会话管理
cookie [2]之外还发出登录
cookie。 - 登录cookie包含用户的用户名,系列标识符和令牌。该系列和令牌是来自适当大的空间的不可猜测的随机数。
- 当非登录用户访问网站并提供登录Cookie时,系统会在用户名,系列和令牌中查找数据库。
- 如果存在三元组,用户
被认为是已认证的。使用的
令牌从数据库中删除。生成一个
新令牌,存储在
数据库中的用户名和
相同的系列标识符,一个新的
登录cookie包含所有三个是
发给 - 如果用户名和系列是
,但令牌不匹配,则假定
a盗用。用户收到
a强烈的措辞警告,并且用户的记住会话的所有
被删除
。 - 如果用户名和系列不是
我在数据库中创建了一个包含以下信息的表:
session |令牌|用户名| expire
记住我的cookie会有这个设置:
$ value =$ session | $ token | $ userhash; // Total length = 106
-
/ code>将是一个包含40(sha1)
个字符的字符串。 -
在cookie中的userhash
将是32(md5)
个字符。 -
数据库中的用户名 cd将为
正常用户名。 li>
到期
现在将为60天。
脚本:
if(isset($ _ SESSION ['check'])|| $ _SESSION ['check' ]){
//用户登录
} else if(isset($ _COOKIE ['remember'])&& strlen($ _ COOKIE ['remember'])== 106){
// THERE是一个cookie,它是正确的长度40session + 32token + 32user + 2'|'
//现在让我们去检查它...
conncectdb(); //设置连接
//如何保护此脚本形式有害的用户输入?
$ 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完全有效!
//使用相同的会话和另一个令牌创建一个新的cookie。
$ 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';);
//设置整个会话(从数据库的用户详细信息)etc ...
} else if(mysql_num_rows(mysql_query(SELECT user FROM tokens WHERE session ='$ session'AND md5用户)='$ userhash';))== 1)){
// TOKEN不同,会话有效
//这个用户可能受到攻击
//放上一个警告,让用户重新验证(登录)
//删除整个会话(以及来自此用户的其他会话)
} else {
// Cookie在数据库中过期?不太可能...
//以什么方式无效?
}
} else {
//没有cookie,脚本的剩余部分
}
脚本的优点:
- 多次登录。您可以为每台计算机创建新的
会话。 - Cookie和数据库将保持干净。
活动用户在每个
登录时更新那个cookie。 - 开始时的会话检查
确保数据库不会
获得无用的请求 - 如果攻击者窃取了一个cookie,它
会获得一个新的令牌,但不是一个新的
会话。因此,当真正的用户访问
网站的旧(无效)
令牌,但有一个有效的用户会话
组合,用户获得警告
的潜在的盗窃。在
重新验证通过登录一个新的
会话后创建,并且会话
攻击者持有无效。
重新验证确保受害者
真的是受害者,而不是
攻击者。
参考: http://jaspan.com/improved_persistent_login_cookie_best_practice
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).
I think I've found a clever solution!
Advantages of this (complicated?) script:
- When the user successfully logs in with Remember Me checked, a login cookie is issued in addition to the standard session management cookie.[2]
- The login cookie contains the user's username, a series identifier, and a token. The series and token are unguessable random numbers from a suitably large space. All three are stored together in a database table.
- When a non-logged-in user visits the site and presents a login cookie, the username, series, and token are looked up in the database.
- If the triplet is present, the user is considered authenticated. The used token is removed from the database. A new token is generated, stored in database with the username and the same series identifier, and a new login cookie containing all three is issued to the user.
- If the username and series are present but the token does not match, a theft is assumed. The user receives a strongly worded warning and all of the user's remembered sessions are deleted.
- If the username and series are not present, the login cookie is ignored.
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:
- Multiple login. You can create new sessions for each computer you're on.
- Cookie and database will stay clean. Active users renew there cookie every login.
- The session check at the beginning ensures that the database will not get useless requests.
- If an attacker steals a cookie, it gets a new token, but not a new session. So when the real user visits the website with the old(invalid) token but WITH a valid user-session combination the user gets a warning of the potential theft. After re-validating by logging in a new session is created and the session the attacker holds is invalid. The re-validating ensures the victim really is the victim, and not the attacker.
Reference: http://jaspan.com/improved_persistent_login_cookie_best_practice
这篇关于什么是使用登录cookie的相对安全的方式?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!