时间限制,或一次性使用,密码重置令牌?

时间:2013-10-09 02:53:51

标签: security passwords password-recovery

用户忘记密码,(几乎)所有会员网站都需要一种方法来帮助用户重新登录。

我想实施常见的方案:

  1. 用户点击网站,尝试登录,不能,并意识到他们忘记了密码 - 废话!
  2. 用户输入电子邮件地址并点击“忘记密码”
  3. 用户通过密码重置链接获取电子邮件
  4. 以下是我计划如何实现它(C#/ ASP.NET MVC):

    1. 当用户输入电子邮件并点击“忘记密码”按钮时,我的网站将生成一个GUID,将其存储在数据库(member.ResetToken)中的成员实体上,并通过电子邮件向他们发送带有该GUID的链接。 (发送的电子邮件将通知他们只能使用此链接一次)
    2. 用户点击该链接,我的网站会根据网址中的member.ResetToken查找其帐户。如果找到了他们的帐户,请向他们显示密码重置表单,当他们完成重置时,会清除其帐户中的member.ResetToken
    3. 这是我的问题:保持这样(他们可以随时,现在或将来使用该链接重置密码)或添加时间戳以限制他们重置密码的时间长度?

      从用户体验的角度来看,只要你准备好就重置密码的能力很棒,但我想确保我不会忽视一些可能带来的安全问题。

4 个答案:

答案 0 :(得分:9)

您的方案确实有效,但有些方面可以改进。但首先是关于时间限制的原始问题:

让我们问相反的问题:为什么令牌仍然无效?

没有任何优势,当两年后点击重置链接时,用户可以在大约一小时内点击链接,或者他可能忘记了链接(并且可以在必要时请求新的链接)。另一方面,能够阅读电子邮件并不一定意味着攻击者必须破解电子邮件帐户,例如办公室中的开放电子邮件客户端,丢失的移动电话,备份(丢失)USB驱动器......

最重要的改进是,您应该只在数据库中存储令牌的哈希。有权访问数据库(SQL注入)的人可能会要求为他喜欢的任何电子邮件地址重置密码,并且因为他可以看到新令牌,他可以用它来设置自己的密码。

然后我将这些重置信息存储在一个单独的表中。在那里,您可以存储用户标识,散列标记,到期日期以及链接是否已被使用的信息。那时用户不处于特殊状态。

也许我误解了这一点,但重置链接应指向密码重置的特殊页面。当用户进入登录页面时,应该没有特殊处理,登录页面不应该知道有未决的密码重置。

重置令牌应该是不可预测的,这可以通过真正随机的代码实现,从操作系统的随机源读取。

答案 1 :(得分:2)

所以,我在评论中试图避免这种方法存在一些问题。当您在用户密码中存储“确认令牌”时,您基本上已经破坏了他们的密码。

我是一个恶意的人,然后可以获取一大堆电子邮件地址和僵尸网络,并通过密码重置请求充斥您的服务器,并将您的用户锁定在他们的帐户中。当然,您的用户将收到重置电子邮件,但如果我能够足够快地重置密码,可能会有积压的电子邮件(或者,如果您同步执行,我可能会对整个应用程序执行操作)。

我,您的系统的普通用户,可能会尝试重置我的密码,并且无法弄清楚为什么我没有收到重置电子邮件,因为我甚至不知道垃圾邮件文件夹(或者它从未到过)。幸运的是,我只记得密码是什么,但它不再起作用,因为密码现在是一个不透明的GUID,我基本上死在水里,直到我找到重置电子邮件。

以下是您使用的过程。

  1. 生成使用GUID查找的密码重置请求,您也可以通过使用某些私有数据散列该值并将其传递到URL中来避免快速攻击。您还可以通过使该请求仅在一段时间内有效来锁定此请求。
  2. 一旦有人使用有效令牌和您指定的任何其他参数关注该链接,他们就可以更改密码,此时您现在可以安全地更改用户密码
  3. 将密码请求标记为已完成,或将其删除。如果您真的担心如果您真的担心密码,那么您还可以跟踪IP地址或类似信息等信息。
  4. 向用户发送确认他们已更改密码的电子邮件。
  5. 此外,为防止此情况发生,请确保您哈希和salting 用户密码。当你刚用GUID替换密码时听起来并不像你那样做,所以只需要仔细检查。

答案 2 :(得分:1)

用户也忘记重置密码(事情发生)。对于密码存在偏执,我建议将链接生命周期限制在24小时内。这应该绰绰有余。它并没有解决恶意拦截的问题,但总比没有好。

答案 3 :(得分:1)

我会提出以下建议:

  1. 在允许用户点击忘记密码按钮之前需要一些信息。例如,需要电子邮件地址和出生日期。

    理想情况下,您的用户界面不应提供任何允许黑客确定其重置请求是否成功的反馈。您不希望他们将您的页面用于电子邮件地址或DOB。然而,这是一个可用性权衡,所以你是否这样做取决于你真正需要多少安全性。

    您可能还需要考虑使用验证码,这会使暴力和应用程序DoS攻击变得更加困难。

  2. 尽快使一次性令牌过期。在我看来,几个小时就足够了。您永远不应该将电子邮件视为私有 - 除非您在基本协议之上使用安全电子邮件技术(例如PGP)(大多数人不这样做),否则不会。你想要的最后一件事是打开一个黑市,你可以买到和卖出你的GUID,这正是如果他们有无限的生命周期就会发生的事情。

  3. 不要使用GUID。它们不是加密随机的并且是可猜测的。我建议你使用加密随机数生成器并将其转换为base64。