1

当用户忘记密码时,您不应该通过电子邮件发送密码。在他的 Pluralsight 课程“ Hack Yourself First: How to go on the Cyber ​​-Offense ”中,Troy Hunt 指出“SMTP 上没有隐含的传输层安全性”Information Security Stack Exchange 上的这个答案证实,以明文形式(包括通过电子邮件)发送或存储密码是个坏主意。

看来,重置密码的正确方法是不要立即重置它。相反,通过电子邮件向用户发送一个有时间限制的激活链接。这需要用户手动干预,并且在任何阶段都不会通过电子邮件传达密码。

上述信息安全答案描述了如何实施密码重置机制:

无论如何都不要重置用户的密码 - 用户更难记住“重置”密码,这意味着他/她必须要么更改它,要么写下来 - 例如,在他边缘的亮黄色便利贴上监视器。相反,只需让用户立即选择一个新的——这就是他们想要做的。

如果用户忘记了密码,请使用存储在数据库中的随机生成的重置令牌向他们发送安全的一次性重置链接。令牌必须是唯一且保密的,因此在数据库中对令牌进行哈希处理,并在使用链接时进行比较。

基于表单的网站身份验证的权威指南类似地描述了实现:

始终对数据库中丢失的密码代码/令牌进行哈希处理。再次,此代码是密码等效项的另一个示例,因此必须对其进行哈希处理,以防攻击者获得您的数据库。当请求丢失密码代码时,将明文代码发送到用户的电子邮件地址,然后对其进行哈希处理,将哈希值保存在数据库中 - 并丢弃原始代码。就像密码或持久登录令牌一样。

但是用户如何真正知道新密码。它是否重置为某些默认值?它是否更改为需要以某种方式与用户通信的随机生成的密码?

在“ Hack Yourself First: How to go on the Cyber​​-Offense ”中,激活链接会将您带到一个表单,您可以在其中输入新密码。

如果您正在处理一个网站,这可能没问题,您可以进入该网站并与 Web 应用程序交互并选择您自己的新密码。但是使用 .NET Web API 之类的东西,您正在与控制器上的操作进行交互,这些控制器通常应该为您提供数据,而不是用户界面。您不能只给他们一个链接并期望他们用它做某事。

因此,如果您正在处理通过 Web API 进行的身份验证,那么允许用户重置密码并将新密码传达给他们的有效且安全的方法是什么?

4

2 回答 2

7

在这种情况下要记住的是,Web API 就是这样:一个 API。即使可能没有网站,但在某处仍然存在用户界面(实际网站、WPF 应用程序或移动应用程序 - 无关紧要)。所以通常的安全“忘记密码”功能仍然可以实现。

但是,有一个区别。与其发送链接,不如发送令牌本身。UI 然后提供输入令牌的位置。要遵循的步骤如下:

  1. 想要重置其密码的用户转到 UI 中相应的“忘记密码”屏幕。
  2. 提示用户输入他的用户名。
  3. 令牌以明文形式发送到他的关联电子邮件地址。散列版本与例如一小时后的到期时间一起存储在数据库中。
  4. 用户在下一个屏幕中输入令牌。
  5. 如果令牌有效,用户将被带到一个屏幕,他可以在其中输入新密码(无需输入旧密码 - 令牌已经对他进行了身份验证)。

通过电子邮件发送明文令牌听起来有点像通过电子邮件发送密码。然而,它在短时间内过期的事实给了攻击者一个非常小的机会窗口来使用它。此外,令牌是一次性的,并且在使用时被丢弃。

于 2014-04-24T19:48:08.330 回答
1

您在此问题中要解决两个概念:密码重置和所涉及的机制,以及向 Web API 验证用户身份的正确方法。我认为区分它们并首先理解后者很重要。

想象一下,您有一个 Web 应用程序和一个受保护的资源(Web API)。Web API 要求所有调用者必须通过某种机制进行身份验证。允许用户向 Web API 进行身份验证的一种方法是直接向 Web API 提供凭据,但这会带来许多其他问题,例如 Web API 需要存储/维护/访问用户帐户信息,发送密码的安全漏洞以这种方式,Web API 在获取原始凭据等时必须代表用户执行的广泛范围。

您可能听说过 OAuth 2.0,它解决了这些问题。访问受保护资源(Web API)的更好方法是添加授权层。例如,Web 应用程序会显示一个用于输入用户凭据的对话框,然后将其发送到授权服务器并进行验证,从而生成访问令牌。然后,访问令牌可用于代表用户(或代表使用客户端凭据授予的应用程序)验证对 Web API 的调用。使用此流程,Web API 不需要直接对用户进行身份验证,它可以更加轻量级,并且解决了其他流程的许多其他安全问题。有关更多详细信息,请参阅OAuth 2.0 规范

回到您的示例,更好的答案是您在不同级别管理密码重置。您的 Web API 根本不需要知道用户和密码,只需要重置它——它应该只接收一个令牌并验证它。这使您可以使用所需的密码重置方法,并且不会影响对任何下游资源的访问。

于 2014-04-16T17:52:26.723 回答