我在 cookie 中使用 2 个变量(7 天到期),即用户 ID 和哈希。哈希是用户代理和用户 ID 的 sha1 编码。在这种情况下,一些黑客可以登录谁知道被盗 cookie 的浏览器。我应该遵循哪种方式或哪种做法最适合记住我的安全问题?
5 回答
虽然您可以散列 user_id 和 secret_key,但任何拦截此 cookie 的人都可以登录到您的应用程序。除此之外,您还可以让您的记住我的 cookie 很快过时。没有人喜欢陈旧的饼干。
您可以将每个用户上次访问的时间戳存储在您的数据库和 cookie 中。每次您读取 cookie 以使用户登录时,您都会检查两个时间戳是否匹配。如果他们不这样做,则拒绝该用户。如果有,请更新时间戳。
使用此方法,任何时候您的用户返回您的网站,所有旧的 cookie 都会过时。截获 cookie 的黑客现在拥有一个毫无价值的陈旧 cookie,因为他不知道当前 cookie 中的确切时间戳。当然,黑客可以在用户重新登录之前尽可能多地使用新的 cookie。
//check for cookie
if(isset($_COOKIE['remember_me'])) {
// get hash and time stamp from cookie
$hash = substr($_COOKIE['remember_me'],0,40);
$last_visit = substr($_COOKIE['remember_me'],41);
// query your db with $hash and $last_visit
// if hash and time stamp match up
// log in
// store the current time stamp in a variable to use for both
$time = date("Y-m-d H:i:s");
// update the time stamp in your cookie
$cookie = $pass . "-" . $time;
setcookie('remember_me', $cookie, time()+60*60*24*100, '/');
// update the time_stamp in your database
else {
// remove the remember me cookie
setcookie('remember_me', '', time()-42000, '/')
}
这种方法提供了少量的安全性,当然应该与其他答案中提出的辅助方法一起使用。散列密钥应存储在 cookie 中。记住我的 cookie 不能完全安全,因此对高度敏感数据或应用程序功能的任何额外访问都需要重新输入密码。
我还建议将您的 cookie 命名为“remember_me”之外的其他名称,以使其更难找到。虽然它不会增加太多安全性(如果有的话),但将您的 cookie 命名为“ht33424”所花费的时间与将其命名为“remember_me”或“hack_me”一样长。
您可以简单地将到期日期设置为现在加上 cookie 上的一年,然后在所有敏感区域都有一个输入密码字段,就像亚马逊使用的实现一样。被劫持的 cookie 将授予访问权限,但购买或修改任何个人内容需要重新输入密码。
“记住我”表的问题在于,如果黑客可以访问该表,他可以创建并登录任意数量的帐户。您可以争辩说它增强了记住我功能的安全性,但需要权衡软化膝盖安全区域的风险。
就个人而言,我创建了一个随机散列并将其存储在“记住我”表中。该表还包含用户代理、用户 ID 和 IP 地址。每次我从记住我功能重新登录用户时,我都会检查两者。如果用户手动注销,我只需从表中删除该行。然后,如果他们再次登录,它会创建一个新的随机散列。真的没有办法用记住我的系统来对付嗅探数据包的人(除非你使用带有 HTTPS only 标志集的安全 cookie)。因此,请使用仅限 HTTPS 的 cookie 的安全连接。如果你不能,那么至少让散列随机,所以如果发现它,你至少可以生成一个新的散列来杀死那个登录......
您最终可以使用会话来存储用户状态。但是长时间保持会话会导致同样的问题,当会话 id 会被盗。您可以将 cookie 信息与其他一些 - 例如浏览器或 IP 地址相结合,但当用户没有静态 IP 时,它会导致问题。
无论如何,持有会话 ID 比将用户的 sha1 结束密码放入 cookie 更安全。
HMAC
我通常这样做,所以我没有任何东西可以存储在服务器端的数据库或类似的东西上。
您必须生成成为您的“密钥”的随机字符串,并且您必须将其存储在服务器端(可能在配置 php 脚本中作为常量)并且您永远不会告诉任何人。我将把这个密钥称为密钥SECRET_KEY
。
然后你的 cookie 必须设置两个值:
USER_ID
: 将获得自动登录的用户的用户 IDHASH
USER_ID
:和的安全加密哈希SECRET_KEY
。所以,例如,md5(USER_ID . "-" . SECRET_KEY)
。(与 md5 不同的东西,例如 sha1 或 sha256 是首选)。
所以你最终的 cookie 可能是:USER_ID:HASH
.
然后,当您必须检查 cookie 是否是真正的记住我 cookie 时,您必须这样做:
function isCookieGenuine($cookie_value) {
list($value, $hash) = explode(':', $cookie_value, 2);
if (md5($value . "-" . SECRET_KEY) == $hash)
return true;
else
return false;
}
关键是只有您可以生成通过此检查的哈希,因为哈希不仅需要服务器以外的任何人都不USER_ID
知道SECRET_KEY
的哈希!:)
如评论中所述,您可以通过使用hash_hmac
PHP >= 5.1.2 中的函数来执行此操作:http: //us.php.net/manual/en/function.hash-hmac.php