【问题标题】:Is it inadvisable to store a hashed password in session?在会话中存储散列密码是否不可取?
【发布时间】:2012-11-29 11:28:49
【问题描述】:

在(服务器端)会话中的用户对象中存储散列密码是否不可取?不用说,在某个时候需要检索加盐和散列的密码以比较散列以验证给定用户,但是一旦进行比较,是否存在与将其保存在用户对象中相关的可量化安全风险?


鉴于 cmets 中的讨论,问题的要点是密码和哈希数据将存储在用户对象中,一旦从数据库中检索到其余用户数据,则只需一次干净的调用。在发布这个问题之前,我明白当然存在风险,但它是否足以保证实施一个框架以从用户那里清除它,或者这样做只是一种良好的做法? p>


鉴于响应,我认为最好的解决方案是拥有一个凭据对象,其中包含通过 ID 与用户关联但不直接存储在其中的密码和盐。

当用户尝试登录时,会通过电子邮件/用户名从数据库中检索用户对象(不包含密码数据)。然后读取 ID 并将其用于检索关联的凭证对象。然后可以进行密码验证。如果密码正确,用户将进入会话并销毁凭据对象。

结果是一个没有密码数据的用户对象,因此可以避免任何潜在的相关安全风险(尽管它们可能很小,如问题中所述)。另一个结果是在用户对象使用之前没有手动清除用户对象的密码数据。这是一个比要求每次都清除数据更可靠的系统,并且如果使用 EF 或类似技术,则不会在将对象的更改推送到数据库时意外擦除密码数据。

【问题讨论】:

  • 如果会话被破坏并且哈希被用作某些“模拟或提升代码”中的直接比较,那么一个攻击向量可能会为另一个用户(例如管理员)注入哈希。虽然我不会说这是“不安全的”(因为它假设会话受到损害,这会引发许多其他问题),但我会说它“可能不太安全”。
  • 通常您会保留一个变量来指示用户已通过身份验证。这样就完全不需要保留密码了。
  • @pst 密码?我需要恢复它,因此它将在单个 EF 调用中折叠到用户对象中。
  • 我永远不会将数据库中的哈希值加载到服务器端代码中......只需计算哈希值(在代码中甚至更好地在数据库中)并始终在数据库上进行比较-侧面......这样任何攻击都可以检索到真正的哈希的唯一地方是数据库......不确定是否值得,但将攻击面缩小到数据库。
  • 问题的实际重点不是“密码是否应该保留在会话中”,而是“应该建立一个框架以确保它永远不会保留在会话中”。跨度>

标签: c# asp.net asp.net-mvc security passwords


【解决方案1】:

我个人认为没有任何理由不这样做。如果加盐哈希是安全的,那么将其存储在服务器端会话中的安全性应该不会低于将其存储在数据库中。

毕竟,使用良好的加盐散列的全部意义在于,即使您的数据库遭到破坏并且有人获得了所有加盐散列,他们仍然无法恢复实际密码。

【讨论】:

【解决方案2】:

假设您信任您的服务器,我认为这不会太不安全。

对于理想的密码散列,散列的泄漏并不是非常重要的。如果盐没有暴露,那么实际上不可能恢复密码。如果构造散列的盐和元素被暴露(除了密码),那么它变得可能,但通常是不切实际的,因为彩虹表是无用的并且暴力是唯一的方法。如果您使用强大的散列算法,例如 SHA256 或 Bcrypt,您不必担心太多..

话虽如此,我绝对不建议只给陌生人密码哈希,但将其保存在您的服务器上应该几乎没有安全隐患

【讨论】:

    【解决方案3】:

    如果您的会话未针对客户端站点存储进行序列化,则不存在与此相关的即时威胁。但是,如果您必须在会话中存储哈希,那么您应该修改您的身份验证/授权逻辑以获得更好的应用程序设计。

    【讨论】:

    • 我怀疑他是否真的需要将哈希存储在会话中。很可能他只是在会话中存储了一个“用户”对象,而该对象恰好具有哈希作为其属性之一。
    • 非常正确,可能是个好主意,但如果他稍后尝试基于该对象进行更新并无意中清除了数据库中的哈希值,可能会导致问题。尽管是否真的有必要这样做,但这仍然是一个很好的问题。
    • 是的,你们理解问题的要点;)。
    猜你喜欢
    • 2010-12-06
    • 2011-01-22
    • 1970-01-01
    • 2013-11-04
    • 2013-07-25
    • 2011-01-20
    • 2016-05-16
    • 2012-01-22
    • 2011-09-28
    相关资源
    最近更新 更多