【问题标题】:Store password hash in session. Good Idea?在会话中存储密码哈希。好主意?
【发布时间】:2015-05-28 14:09:37
【问题描述】:

总结问题

有哪些论据支持或反对在会话中保存密码哈希?

想法

在登录时将密码哈希(在数据库中)存储在会话中,并在每次访问时根据数据库哈希对其进行验证,以便在密码更改时自动使所有会话无效。

我的想法

这些是我目前对这个主题的想法。

专业版

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

骗局

  • 如果 A 在 B 更改密码后立即提交表单,可能会丢失数据。
  • 假设恶意攻击,攻击者可以踢出合法用户。

中性

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

请回答和评论

我不想在这里开始主观讨论。我想收集(尽可能客观)关于该主题的利弊。我还没有考虑什么?

编辑:

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

【问题讨论】:

  • 我会问为什么会话会因为密码更改而失效?
  • 如果您只想在更改密码时使会话无效,我会使用某种“最后修改日期”并使用它。这不是防止会话劫持的正确方法,所以如果你想防止这种情况,也许谷歌寻找另一种防止会话劫持的解决方案。 (最后一部分只是一个假设)
  • @DarkFalcon 这是我的一个想法。这个想法类似于“如果一个人在其他人不知道可能有原因的情况下更改密码,那么他们应该立即失去访问权限”。那时我并没有考虑恶意用户。

标签: php apache security session


【解决方案1】:
  1. 同时更改密码的场景听起来极为罕见,这不是构建会话架构的核心前提。乐观锁定和其他并发解决方案也可以更好地防止这种情况发生。
  2. 您可以在显式更改密码时使会话无效,您无需为此在会话中存储密码。如果您使用数据库来存储会话(最好是内存数据库,如 Redis 或 memcached),这很简单,但使用标准的基于 PHP 文件的会话也不是不可能的。更改密码后,只需主动取消指定用户的所有活动会话即可。
  3. 密码是一个秘密,应尽可能避免流通。哈希只是那个秘密的影子,但即使是它你也应该保密。将其存储在会话中比将其纯粹保存在数据库中更接近意外泄漏。
  4. 在每个页面加载时执行数据库查找都会影响性能。

【讨论】:

  • 关于 4. 我应该提到我在每次页面加载时都会加载用户,因为其他原因。关于 1. 以前我们不是都曾遭受过有人说“这非常罕见,永远不应该发生”吗? ;) 关于 2. 和 3.:好点!
  • 我并不是说它非常罕见,您不必担心。我的意思是,在您的会话存储设计中用作主要支柱太少见了。
  • 此外,在每个页面加载时查询数据库以获取用户信息是相当消耗性能的。典型的架构是在登录时将相关信息的副本存储在 fast 数据存储中。文件没问题,内存存储更好。当后端的数据发生更改时,您将更改的数据推送到存储的副本,和/或使该副本无效。
【解决方案2】:

建议:

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

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

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

什么都不会发生在我身上,因为我的令牌仍然有效(您可以创建一个表来保存具有到期日期列的有效令牌)

【讨论】:

  • 对...根本没有考虑令牌。谢谢。
猜你喜欢
  • 1970-01-01
  • 2015-10-07
  • 2017-10-05
  • 2011-11-17
  • 1970-01-01
  • 2019-07-19
  • 2023-03-24
  • 2020-11-18
  • 1970-01-01
相关资源
最近更新 更多