Sup*_*Spy 9 php cookies autologin
我想知道最安全的cookie登录方式是什么?如果您只是将通行证(使用salt加密)和用户名存储在cookie中并根据用户表进行验证,则潜在的攻击者可以窃取cookie并登录.人们通常不会检查'上次在线'.
那么"记住我的饼干"有更好的方法吗?IP不是一个好选择,是吗?(有些机器一直在更换IP).
Sup*_*Spy 20
我想我找到了一个聪明的解决方案!
这个(复杂的?)脚本的优点:
我在数据库中创建了一个包含以下信息的表:
session | token | username | expire
Run Code Online (Sandbox Code Playgroud)
记住我的cookie将有这个设置:
$value = "$session|$token|$userhash"; //Total length = 106
Run Code Online (Sandbox Code Playgroud)
Session 将是一个由40个(sha1)字符组成的字符串.Token 将是一个32(md5)个字符的字符串.Userhash 在cookie中将是一个32(用户名为md5)字符的字符串.Username 在数据库中将是普通用户名.Expire 现在将是+ 60天.剧本:
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
}
Run Code Online (Sandbox Code Playgroud)
脚本的优点:
参考:http://jaspan.com/improved_persistent_login_cookie_best_practice
这种"记住我"功能总是存在额外的安全风险.
因为就像在会话中一样,你只有一个标识符,不仅可以识别用户(是谁?),而且还可以在不进行实际身份验证的情况下对该用户进行身份验证(是真的是他/她吗?).
但是与具有(或应该具有)短寿命(大多数不到一小时)的会话相反,并且标识符(或应该)定期更改(由于真实性/权限状态更改而基于时间和必要性) ,"记住我"标识符有效期为几天甚至几个月或几年!这种长期有效期会带来额外的安全风险.
因此,在询问如何实现这样一个"记住我"功能之前,您应该问问自己是否真的需要额外的安全风险.这主要取决于您的应用程序具有的资产以及身份验证的目的,以及您是否希望冒"模仿我"功能所带来的冒充/身份盗窃的风险.
如果是这样,请确保使用HTTPS提供基本安全性,并在cookie中设置HTTPOnly标志和安全标志.然后你可以做以下事情来构建这样一个"记住我"的功能:
身份验证请求
如果用户通过HTTPS进行身份验证并设置"记住我"选项,则生成一个随机记住我的令牌,将其存储在服务器端的"记住我"数据库中,并使用安全标记设置记住我的 cookie 值.然后开始一个新的会话并设置一个记住我的标志.
任何其他要求
通过这种方式,身份验证通过HTTPS进行保护,包括初始身份验证和"记住我"身份验证.并且用户在当前会话期间仅是可信的; 如果它到期,则用户必须使用记住我令牌或提供他/她的登录凭证来重新进行身份验证.由于记住我的令牌存储在数据库中,用户可以使任何现有的记住我令牌无效.
最流行的方式:
许多脚本使用某种会话跟踪。当用户第一次访问网站时,它会为用户生成一个唯一的随机 ID,并将会话信息存储在服务器中,并将 ID 存储在 cookie 中。然后服务器使用唯一 ID(称为会话 ID)识别用户。与会话 ID 关联的信息只能由服务器看到。PHP 默认使用这个,
有些将用户数据存储在 cookie 本身中,但具有使用秘密字符串作为密钥的 HMAC 签名。如果签名不匹配,脚本将丢弃 cookie。这样,服务器不必将会话数据保存在服务器上。用户通过查看 cookie 来查看会话中的内容,因此您不应在其中存储敏感数据。仅用户 ID(可能还有登录时间和 cookie 到期时间)就足够了。虽然用户可以看到会话信息中的内容,但 cookie 中的签名确保用户不能自己修改会话数据。
这些方式提供了一些安全性,即用户不能篡改会话数据,但不能保护用户免受窃听。他们总是可以使用数据包嗅探器并从任何开放的 WiFi 网络窃取会话。某些应用程序确实依赖于用户 IP,但攻击者是否在同一网络中并不重要。有些应用依赖 User-Agent,但当用户更新浏览器或从其他浏览器导入数据时就会出现问题。
如果您真的很关心安全性,请使用 HTTPS。
另请阅读这篇文章,尤其是名为网站运营商如何解决问题的部分?
| 归档时间: |
|
| 查看次数: |
18098 次 |
| 最近记录: |