【问题标题】:.NET Web API Password reset.NET Web API 密码重置
【发布时间】:2014-05-31 07:50:49
【问题描述】:

当用户忘记密码时,您不应通过电子邮件发送密码。在他的 Pluralsight 课程“Hack Yourself First: How to go on the Cyber-Offense”中,Troy Hunt 指出“SMTP 上没有隐式传输层安全性”。信息安全堆栈交换上的This answer 确认以明文形式(包括通过电子邮件)发送或存储密码是个坏主意。

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

前面提到的Information Security answer 描述了如何实现密码重置机制:

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

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

The definitive guide to form based website authentication 类似地描述了实现:

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

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

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

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

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

【问题讨论】:

    标签: security authentication passwords asp.net-web-api reset-password


    【解决方案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 specification

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

    【讨论】:

    • 您提出了很好的观点 - 但与问题并不完全相关。这可能是我的错,因为我没有具体说明情况;但是我正在假设 Web API 已经使用 SSL、HMAC 令牌和其他任何东西(没有 OAuth)是安全的,并且您只需要为用户提供一种机制来重置他的密码(并将该密码传达给他)。
    • 我可能误解了您的要求。我的回答是试图建议您应该重新考虑让 Web API 完全验证和重置密码(这本质上会改变问题的性质)。您是说您希望用户能够直接对 Web API 进行身份验证(两者之间没有客户端应用程序),并且让 Web API 也能够重置他们的密码?
    • 是的......虽然总是有一个客户端应用程序来与 Web API 通信,但本质上我确实希望 Web API 来处理身份验证和密码重置。我可能已经想出了怎么做……我会在接下来的几天里尝试一个实现,如果可行,我会发布一个答案。
    【解决方案2】:

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

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

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

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

    【讨论】:

      猜你喜欢
      • 2018-07-31
      • 1970-01-01
      • 2018-01-29
      • 1970-01-01
      • 2018-07-07
      • 1970-01-01
      • 2016-06-17
      • 2019-07-21
      • 1970-01-01
      相关资源
      最近更新 更多