6

我希望我的用户在登录我的网站时能够“保持登录状态”。在这篇文章的最佳答案的建议下,“让我登录” - 最好的方法,我决定在一个 cookie 中散列用户的盐和密码的组合,并将用户的 id(一个数字)存储在另一个 cookie 中。当然,哈希值也将存储在数据库服务器端,以供用户再次返回时进行验证。我使用的盐值与我在用户第一次注册时用来散列用户密码的值相同,因此它是静态的 - 它在会话之间不会改变。我看到这种方法存在一些问题。

1)如果它是静态的,或者我应该每次为cookie生成不同的盐,使用注册盐是一个好主意吗?

2)如果有人获得了cookies的访问权,他们将它们复制到另一台计算机上,然后尝试从该计算机访问该网站,理论上它会自动将其登录到该用户的帐户,这不是安全问题吗?

3) 在某些怀有恶意意图的用户要访问数据库的情况下,安全网站会使用加盐和散列密码,使黑客很难访问多个帐户(如果有的话)。但是,通过简单地使用散列值和盐值并创建一个与他们在数据库上更改的值相匹配的 cookie,他们可以有效地访问他们想要的任何帐户,从而使整个密码散列过程变得毫无用处。因此,我现在使用的这种 cookie 方法正在损害我的整个数据库和所有用户的帐户。

所以我的问题是,如何在 PHP 中存储包含敏感信息(例如用户密码哈希)的 cookie,而不必担心上述问题?当然,提供“保持登录”功能的 Gmail 和 Hotmail 等网站采用了比我现在所做的更安全的方法,那么他们会怎么做呢?

4

1 回答 1

11

不要将密码存储在 cookie 中,无论是否经过哈希处理。事实上,没有理由在 cookie 中存储任何敏感信息。您需要做的就是将一个 128 位(或更大)的随机 id 映射到数据库中的用户帐户,并将该 id 存储在 cookie 中。没有办法有人会通过远程蛮力猜测一个有效的 id,特别是如果你有锁定的地方。

如果有人要访问cookies并将它们复制到另一台计算机上,然后尝试从该计算机访问该网站,理论上它会自动将它们登录到该用户的帐户,这不是安全问题吗?

是的。这是该功能的缺点。但是,如果您的网站检测到新的 IP 地址(特别是来自不同国家/地区)并需要第二步(将代码发送到移动设备等),那么您将处理此问题以及密码被盗的一般问题。(这当然无助于防止本地网络攻击,例如不安全的公共 wifi。)

更方便的解决方案是要求“记住我”cookie 使用 SSL。这样一来,黑客就不会在纯文本传输中看到 cookie,并且可能需要进行本地攻击。(如果是这样,记住我的 cookie 可能是用户最不关心的问题。)

他们可以有效地访问他们想要的任何帐户,从而使整个密码散列过程变得毫无用处。

是的,没有。如果您使用我描述的技术(随机 id),那么他们只能访问具有“记住我”cookie 的帐户。但话虽如此,如果他们有权访问您的数据库,他们可以暴力破解他们想要的任何帐户。如果密码本身很弱,即使是加盐密码也很容易在本地破解。

此外,您可以将“记住我”登录视为半登录。访问购买东西、更改电子邮件地址等仍然需要输入密码。无需密码即可进行无害的操作,例如在留言板上发帖。

最后,请注意 PHP 会话 cookie 只不过是一个临时的“记住我”令牌!这在很大程度上适用于会话劫持的概念。“记住我”令牌只是增加了一个更大的机会之窗。

简而言之:不要在 cookie 中存储任何敏感信息,cookie 需要 SSL,如果可能,实施多因素身份验证……尤其是对于管理员帐户。

于 2012-08-05T06:15:55.217 回答