在会话中存储密码哈希值.好主意


Store password hash in session. Good Idea?

总结问题

支持或反对在会话中保存密码哈希值的参数是什么?

<标题> 想法

在登录时将密码哈希存储在会话中(就像它在DB中一样),并在每次访问时根据DB哈希验证它,以便在密码更改时自动使所有会话无效。

<标题>我的想法h1> 些是我到目前为止对这个问题的看法。

Pro

  • 假设两个人合法地共享一个帐户,它将(主要)防止一种竞争条件,即当另一个人登录时,两人都更改密码。混淆只会发生一次而不是两次。
  • 假设恶意攻击,如果发现得足够早,合法用户可以踢出攻击者。

监狱
  • 如果A在B修改密码后提交表单,可能会导致数据丢失。
  • 假设存在恶意攻击,攻击者可以将合法用户踢出。

中性

  • 没有实际的性能影响。(编辑:因为我加载用户信息在每个页面加载无论如何其他原因。)
  • 安全问题几乎不存在。如果有人可以访问服务器,那么访问包含所有哈希值的数据库的工作量与访问会话存储(包含登录用户的哈希值)的工作量相当。

请回答和评论

我不想在这里开始一个主观的讨论。我想(尽可能客观地)收集关于那个问题的利弊。我还没有考虑到什么?<标题>编辑:

澄清:使所有会话(用于更改密码的会话除外)无效的想法来自这样一种想法:"如果一个人在没有告诉其他某些人的情况下更改密码,那么他们应该立即失去访问权限",假设没有恶意用户(这将是一个多么美妙的世界……)。

  1. 同时更改密码的场景听起来非常罕见,也不是构建会话体系结构的核心前提。乐观锁定和其他并发性解决方案也可以更好地防止这种情况。
  2. 当密码显式更改时,您可以使会话无效,您不需要为此在会话中存储密码。如果您使用数据库来存储会话(最好是内存数据库,如Redis或memcached),这是微不足道的,但使用标准的PHP基于文件的会话也不是不可能的。当密码更改时,只需主动销毁给定用户的所有活动会话,完成。
  3. 密码是一个秘密,应该尽可能远离流通。哈希值只是那个秘密的影子,但即便如此,你也应该保密。将它存储在会话中比将它纯粹保存在数据库中更容易意外泄漏。
  4. 的性能影响做数据库查找每一个单一的页面加载。

建议:

你可以生成一个"令牌",而不是在会话中存储你的密码哈希值,在这里你可以生成一个随机的字符和数字序列,并将其存储在会话中,并给它一个过期时间。

让我们假设你和我共享一个密码为cow123的帐户。当我登录时,我收到令牌$124abc,你收到令牌%xyz222,这两个令牌都与密码cow123有关。

现在您将密码cow123更改为cat321。

我不会发生任何事情,因为我的令牌仍然有效(您可以创建一个表来保存具有过期日期列的有效令牌)