您在会话中存储密码的"暴露"程度如何?



我正在使用Python和Flask制作一个网站,我想知道一些对我来说相当重要的事情。

在过去,作为一个没有受过教育的程序员,我总是在会话中保存未加密的用户密码,以便在请求时重新验证用户名和密码。目前我正在制作我的第一个严肃的网站,所以我也想做得更好。

我知道有一些方法可以嗅探会话变量,例如通过某种方式获取另一个人的会话ID。我想知道最好以何种形式存储密码,以向有权访问会话数据的人隐藏密码。

到目前为止我想到的选项:

  • 未加密:逻辑上最糟糕的选项
  • 哈希:例如,将sha256(password)保存到会话中。这也不是一个好的选择,因为破解者可以使用字典表来检索未加密的密码
  • 盐渍&散列:例如,将sha256(password+hash)保存到会话中。这是三个选项中最安全的一个,但它将是数据库条目的副本,对我来说这似乎不是一个好主意。破解者可以将自己的密码与自己的哈希进行比较,并可能找出如何为整个数据库创建盐和哈希。我不确定这是否是一个合理的问题,但我想Stackoverflow上知识渊博的用户会告诉我。)
  • 盐渍&散列,数据库保存一个递归散列字符串:本质上,这似乎是一个不错的选择,但我读到递归散列密码总是一个坏主意

那么,以下哪一项是推荐的呢?也许是我没想到的第五个?请注意,这个变量需要用于验证用户的凭据,所以我们不能用不同的salt对其进行散列。

为什么需要在会话中存储用户密码?我看不出有什么特别的需求,它只是无端地制造了潜在的安全风险。

相反,只需存储用户名,可能还有一个标志,说明用户已通过身份验证。当然,当用户注销时,您应该清除标志(和/或只清除整个会话数据),这样,以某种方式访问旧会话cookie的攻击者就无法在注销后恢复会话。

您可能还想在会话中存储"上次访问"时间戳,这样就可以让旧的过时会话超时。或者,您可以依赖会话框架内置的会话过期行为,但将备份机制完全置于应用程序的直接控制之下可能仍然是个好主意。

Ps。显然,无论您做什么,都要确保您的会话标识符是使用加密安全的随机数生成器生成的(例如Crypto.random随机),并且它们足够长,不可访问(至少64位=16个十六进制数字,尽管128位更好)。如果由于某种原因,不能这样做,另一种选择是自己生成这样一个随机令牌,将其存储在会话和cookie中,并在使用任何实际会话数据之前验证会话和cookie令牌是否匹配。

最新更新