Php 在会话中存储密码哈希。好主意 总结问题

Php 在会话中存储密码哈希。好主意 总结问题,php,apache,security,session,Php,Apache,Security,Session,支持或反对在会话中保存密码哈希的参数有哪些 主意 登录时在会话中存储密码散列(在DB中),并根据每次访问时的DB散列进行验证,以便在密码更改时自动使所有会话无效 我的想法 这些是我到目前为止对这个问题的看法 赞成 假设两个人合法地共享一个帐户,那么(大部分情况下)可以防止在另一个人登录时双方都更改密码的情况。混乱只会发生一次,不会发生两次 假设发生恶意攻击,如果及早发现,合法用户可能会将攻击者赶走 骗局 如果人员A在人员B更改密码后立即提交表单,则可能会丢失数据 假设存在恶意攻击,攻击者可

支持或反对在会话中保存密码哈希的参数有哪些

主意 登录时在会话中存储密码散列(在DB中),并根据每次访问时的DB散列进行验证,以便在密码更改时自动使所有会话无效

我的想法 这些是我到目前为止对这个问题的看法

赞成
  • 假设两个人合法地共享一个帐户,那么(大部分情况下)可以防止在另一个人登录时双方都更改密码的情况。混乱只会发生一次,不会发生两次
  • 假设发生恶意攻击,如果及早发现,合法用户可能会将攻击者赶走
骗局
  • 如果人员A在人员B更改密码后立即提交表单,则可能会丢失数据
  • 假设存在恶意攻击,攻击者可以驱逐合法用户
中立的
  • 没有实际的性能影响。(编辑:因为我在每个页面上加载用户信息,但出于其他原因,还是加载了。)
  • 安全问题几乎不存在。如果有人可以访问服务器,那么访问包含所有散列的数据库的努力与访问包含loggedin用户散列的会话存储的努力相当
请回答和评论 我不想在这里开始主观的讨论。我想收集(尽可能客观)关于这个问题的赞成和反对意见。我还没有考虑什么

编辑:
澄清:使所有会话(用于更改密码的会话除外)无效的想法来自“如果一个人更改密码而不告诉其他人原因,那么他们应该立即释放访问权限”,假设没有恶意用户(那将是一个多么奇妙的世界……。

建议:

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

假设您和我使用密码cow123共享一个帐户。当我登录时,我将收到令牌$124abc,您将收到令牌%xyz222,这两个令牌都与密码cow123相关

现在您将密码cow123更改为cat321

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

  • 同时更改密码的场景听起来非常罕见,并且不是构建会话体系结构的核心前提。乐观锁定和其他并发解决方案也可以更好地防止这种场景
  • 当密码被显式更改时,您可以使会话无效,您不需要为此在会话中存储密码。如果您使用数据库存储会话(最好是内存中的数据库,如Redis或memcached),这是很简单的,但使用标准的基于PHP文件的会话也不是不可能的。只要在密码更改时主动取消给定用户的所有活动会话即可
  • 密码是一个秘密,应该尽可能避免传播。哈希只是该秘密的一个影子,但即使是你也应该保密。将其存储在会话中比将其完全保存在数据库中更接近意外泄漏
  • 在每次加载页面时执行数据库查找会对性能产生影响

  • 我会问为什么会话会因为密码更改而无效?如果您只是想在密码更改时使会话无效,我只会使用某种“上次修改日期”使用它。这不是防止会话劫持的正确方法,因此,如果你想防止会话劫持,也许可以通过谷歌寻找另一种防止会话劫持的解决方案。(最后一部分只是一个假设)@DarkFalcon这是我想到的一个想法。这个想法与“如果一个人在其他人不知道可能有原因的情况下更改密码,那么他们应该立即失去访问权限。”我当时没有考虑恶意用户。大约4.我应该提到,我在每个页面上加载该用户是出于其他原因。大约1.有人说,我们不是都很痛苦吗?”这是极为罕见的,不应该发生在“以前”;)关于2.和3.:好的观点!我不是说它非常罕见,以至于您不必担心它。我是说它太罕见了,无法用作会话存储设计的主要tentpole。此外,在每个页面加载时查询数据库以获取用户信息是一个相当大的性能消耗。典型的体系结构是,在登录时存储一份将相关信息存储在快速数据存储中。文件可以,内存存储更好。当后端的数据更改时,您将更改的数据推送到存储的副本,并/或使该副本无效。对…根本没有考虑令牌。谢谢。