【问题标题】:How to store cookies containing sensitive data securely in PHP?如何在 PHP 中安全地存储包含敏感数据的 cookie?
【发布时间】:2012-08-02 14:26:33
【问题描述】:

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

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

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

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

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

【问题讨论】:

    标签: php security cookies login hash


    【解决方案1】:

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

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

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

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

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

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

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

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

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

    【讨论】:

    • 很好的答案,谢谢。所以我将使用类似 uniqid() 的东西来生成一个用于记住登录的令牌。如果数据库遭到破坏,攻击帐户是多么容易,我仍然不满意。如果不包括整个“记住我”机制,我可能会检测到入侵并在任何严重损害发生之前采取行动,但使用这种解决方案,攻击几乎是即时的。
    • uniqid() 虽然唯一性并不难预测。我会使用类似 base64 编码的openssl_random_pseudo_bytes()。您的担忧是有道理的,但同样,健全性检查将防止广泛的攻击。例如,如果您有很多新 IP 登录旧帐户或一个 IP 登录多个帐户,请举旗。
    猜你喜欢
    • 2013-08-01
    • 2012-03-28
    • 2014-09-30
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2017-09-15
    • 2017-01-14
    • 1970-01-01
    相关资源
    最近更新 更多