2010-08-20 59 views
8

我在cookie中使用2个变量(7天过期),这是用户ID和散列。哈希是用户代理和用户标识的sha1编码。在这种情况下,一些黑客可以登录谁是知道被盗的cookie的浏览器。我应该遵循哪种方式或哪种做法最适合记住我的安全问题?记住我的最佳做法功能

+0

相关:http://stackoverflow.com/search?q=php+session+hijacking – 2010-08-20 13:47:46

+0

只要可能,您应该重新使用现有的身份验证框架,因为它确实很复杂。例如,看看https://github.com/delight-im/PHP-Auth – caw 2016-09-21 02:53:03

回答

6

虽然你可以散列为user_id和SECRET_KEY,谁拦截这个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'即可。

+0

对不起,但我不认为我喜欢这个答案,除非我误解它的逻辑,这依赖于用户在黑客有时间复制并执行页面之前加载新页面。在真正的用户会话结束时,存在劫持的大窗口,即使在会话期间,在页面加载之间也不应太难。这会为真正的用户创建不寻常的页面行为。重命名cookie变量名称是安全的,因为它隐藏并浪费时间。 (续) – 2010-08-23 09:08:26

+0

......这可能是另一个层面,但一个坚定的黑客不会被它感染。由于我上面提到的原因,它不是100%安全的。对于敏感和潜在的破坏性访问敏感信息和功能,我不会推荐这种方法作为100%安全的解决方案,只是一个小小的改进。 – 2010-08-23 09:10:34

+0

对于一个确定的黑客来说,没有任何方法是100%安全的。正如你所说,这实际上只是一个尝试让我们更接近100%的层。这意味着与其他方法一起使用,其中许多方法在其他答案中提供。散列键肯定应存储在cookie中,并且需要重新输入密码才能更多地访问敏感信息和功能。 – SomewhereThere 2010-08-23 12:58:53

0

就我个人而言,我创建一个随机散列并将其存储在“记住我”表中。该表还具有用户代理,用户标识和IP地址。每次我通过记忆功能重新登录用户时,都会检查两者。如果用户手动注销,我只需从表中删除该行。然后,如果他们再次登录,它会创建一个新的随机哈希。实际上没有办法与记住我的系统来嗅探数据包(除非您使用HTTPS only标志设置的安全cookie)。因此,请使用与HTTPS专用Cookie的安全连接。如果你不能,那么至少使随机散列,所以如果它被发现,你至少可以生成一个新的哈希来杀死该登录...

+0

小心解释-1? – ircmaxell 2010-08-20 14:18:26

+0

不是我,但我总是对这样的执行保持警惕,因为它假定像user agent和ip这样的变量在常常不是常量时是常量。我不会将此定义为解决方案,但更多的解决方法是 – 2010-08-20 14:37:24

+0

。但是在缺乏HTTPS cookie的情况下,是否真的有更好的方法来验证源代码? – ircmaxell 2010-08-20 14:40:10

0

您最终可以使用会话来存储用户状态。但是,持续会话很长时间会导致同样的问题,会话ID将被盗用。您可以将cookie信息与其他浏览器或IP地址一起加入,但当用户没有静态IP时会导致问题。

无论如何,持有会话ID更安全,只需将用户的sha1密码输入到cookie即可。

+0

幸运的是,OP没有谈论密码:)但是,会话ID在这里可能很有用。 – Piskvor 2010-08-20 14:00:04

+0

长时间运行会话几乎总是一个坏主意。它们打开了特定DOS攻击的大门,因为您可以占用非微不足道的存储空间,因为PHP在达到时间限制之前无法GC会话。在某些情况下,它是必要的,但大多数情况下它不是一个好主意...... – ircmaxell 2010-08-20 14:04:15

0

HMAC

我通常做这种方式,所以我没什么可存储上的数据库或类似的服务器端。

你必须生成随机字符串,成为你的“秘密密钥”,你必须在服务器端存储(可能在一个配置php脚本作为常量),你永远不会告诉任何人。我会叫这个密钥SECRET_KEY

那么你的cookie必须设置两个值:

  • USER_ID:中USER_IDSECRET_KEY一个安全的加密哈希:这将让自动登录
  • HASH用户的用户ID。所以,例如,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; 
} 

的一点是,只有你可以生成通过此检查,因为一个哈希hash不仅需要USER_ID,还需要SECRET_KEY,这是服务器以外的人所不知道的! :)

正如评论指出的,你可以通过使用hash_hmac功能在PHP> = 5.1.2做到这一点:http://us.php.net/manual/en/function.hash-hmac.php

+1

太糟糕的数组解引用在PHP中不起作用(它仅在trunk中实现)。所以你可以改为'list($ value,$ hash)= explode(':',$ cookie_value,2);'。如果你为每个用户实施一个不同的“秘密”,那么它对安全可能会更好(因为一次秘密的妥协不会为每个用户打开大门)。呵呵,PHP有一个内置的['hash_hmac'函数](http://us.php.net/manual/en/function.hash-hmac.php)来做这件事... – ircmaxell 2010-08-20 14:07:23

+0

@ircmaxell,+ 1为您的评论(我开始忘记这些事情......我不再写PHP了:))。我正在整合你的提示。我不同意为每个用户创建不同的秘密。虽然这显然更安全,但我认为在这种情况下,优势很小。 – 2010-08-20 14:10:11

1

你可以简单地设置到期日期,再加上一年的cookie,但是在所有敏感区域都有一个输入密码字段,就像amazon使用的实现一样。被劫持的cookie将授予访问权限,但购买或修改任何个人要求重新输入的密码。

“记住我”表的问题在于,如果黑客可以访问此表,他可以创建并登录尽可能多的帐户。你可以争辩说它加强了记住我的功能的安全性,但它需要权衡软化膝盖安全区域的风险。