带有随机数的电子邮件中的激活/注册/密码重置链接的最佳实践是什么

发布于 2024-07-26 00:59:12 字数 1699 浏览 2 评论 0原文

应用程序发送电子邮件来验证用户帐户或重置密码。 我相信以下是应该的方式,我要求参考和实现。

如果应用程序必须在电子邮件中发送一个链接来验证用户的地址,根据我的观点,该链接以及应用程序对该链接的处理应该具有以下特征:

  1. 该链接包含一个 nonce 位于请求 URI (http://host/path?nonce) 中。
  2. 在点击链接 (GET) 后,系统会向用户显示一个表单,其中可以选择包含随机数。
  3. 用户确认输入(POST)。
  4. 服务器接收请求并
  • 检查输入参数,
  • 执行更改
  • 并使随机数无效。

根据关于安全和幂等方法的 HTTP RFC,这应该是正确的。

问题是这个过程涉及一个额外的页面或用户操作(第 3 项),很多人认为这是多余的(如果不是无用的话)。 我在向同行和客户展示这种方法时遇到了问题,因此我要求更广泛的技术团队对此提供意见。 我反对跳过 POST 步骤的唯一论据是可能从浏览器预加载链接。

  • 是否有关于这个主题的参考资料可以更好地解释这个想法并说服非技术人员(期刊、博客等的最佳实践)?
  • 是否有实施此方法的参考站点(最好是流行的且拥有许多用户的站点)?
  • 如果没有,是否有记录的原因或等效替代方案?

谢谢你,
Kariem


省略细节

我保留了主要部分的简短内容,但为了减少围绕我故意遗漏的细节的过多讨论,我将添加一些假设:

  • 电子邮件的内容不属于这次讨论。 用户知道她必须单击链接才能执行操作。 如果用户没有反应,什么也不会发生,这也是众所周知的。
  • 我们不必说明为什么向用户发送邮件,也不必说明通信政策。 我们假设用户希望收到电子邮件。
  • 该随机数具有过期时间戳,并直接与收件人电子邮件地址关联以减少重复。

注释

使用 OpenID 等技术,普通 Web 应用程序无需实施标准用户帐户管理(密码、电子邮件...),但仍然有一些客户想要“他们自己的用户” ’

奇怪的是,我还没有在这里找到令人满意的问题或答案。 到目前为止我发现了什么:

Applications send out emails to verify user accounts or reset a password. I believe the following is the way it should be and I am asking for references and implementations.

If an application has to send out a link in an email to verify the user's address, according to my view, the link and the application's processing of the link should have the following characteristics:

  1. The link contains a nonce in the request URI (http://host/path?nonce).
  2. On following the link (GET), the user is presented a form, optionally with the nonce.
  3. User confirms the input (POST).
  4. The server receives the request and
  • checks input parameters,
  • performs the change,
  • and invalidates the nonce.

This should be correct per HTTP RFC on Safe and Idempotent Methods.

The problem is that this process involves one additional page or user action (item 3), which is considered superfluous (if not useless) by a lot of people. I had problems presenting this approach to peers and customers, so I am asking for input on this from a broader technical group. The only argument I had against skipping the POST step was a possible pre-loading of the link from the browser.

  • Are there references on this subject that might better explain the idea and convince even a non-technical person (best practices from journals, blogs, ...)?
  • Are there reference sites (preferably popular and with many users) that implement this approach?
  • If not, are there documented reasons or equivalent alternatives?

Thank you,
Kariem


Details spared

I have kept the main part short, but to reduce too much discussion around the details which I had intentionally left out, I will add a few assumptions:

  • The content of the email is not part of this discussion. The user knows that she has to click the link to perform the action. If the user does not react, nothing will happen, which is also known.
  • We do not have to indicate why we are mailing the user, nor the communication policy. We assume that the user expects to receive the email.
  • The nonce has an expiration timestamp and is directly associated with the recipients email address to reduce duplicates.

Notes

With OpenID and the like, normal web applications are relieved from implementing standard user account management (password, email ...), but still some customers want 'their own users'

Strangely enough I haven't found a satisfying question nor answer here yet. What I have found so far:

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(3

水水月牙 2024-08-02 00:59:12

这个问题与 非常相似在 ASP.NET (C#) 中实现安全、独特的“一次性”激活 URL

我的回答与您的方案接近,但指出了一些问题 - 例如有效期短,处理双重注册等。
您对加密随机数的使用也很重要,许多人往往会跳过这一点 - 例如“让我们只使用 GUID”...

您提出的一个新观点,这在这里很重要,是关于 GET 的幂等性。
虽然我同意您的总体意图,但很明显,幂等性与一次性链接直接矛盾,而一次性链接在某些情况下是必要的,例如这种情况。

我本想假设这并没有真正违反 GET 的幂等性,但不幸的是它确实违反了......另一方面,RFC 说 GET 应该 是幂等的,它不是必须的。 所以我想说在这种情况下放弃它,并坚持使用一次性自动失效的链接。

如果您真的想要严格遵循 RFC,而不是陷入非幂等(?) GET,您可以让 GET 页面自动提交 POST - 这是一个围绕该位的漏洞RFC,但合法,并且您不需要用户双重选择,并且您不会打扰他...

您实际上不必担心预加载(您在谈论 CSRF 或浏览器优化器吗?)..由于随机数,CSRF 是无用的,并且优化器通常不会在预加载的页面上处理 javascript(用于自动提交)。

This question is very similar to Implementing secure, unique “single-use” activation URLs in ASP.NET (C#).

My answer there is close to your scheme, with a few issues pointed out - such as short period of validity, handling double signups, etc.
Your use of a cryptographic nonce is also important, that many tend to skip over - e.g. "lets just use a GUID"...

One new point that you do raise, and this is important here, is wrt the idempotency of GET.
Whilst I agree with your general intent, its clear that idempotency is in direct contradiction to one-time links, which is a necessity in some situations such as this.

I would have liked to posit that this doesn't really violate the idempotentness of the GET, but unfortunately it does... On the other hand, the RFC says GET SHOULD be idempotent, its not a MUST. So I would say forgo it in this case, and stick to the one-time auto-invalidated links.

If you really want to aim for strict RFC compliance, and not get into non-idempotent(?) GETs, you can have the GET page auto-submit the POST - kind of a loophole around that bit of the RFC, but legit, and you dont require the user to double-optin, and you're not bugging him...

You dont really have to worry about preloading (are you talkng about CSRF, or browser-optimizers?)... CSRF is useless because of the nonce, and optimizers usually wont process javascript (used to auto-submit) on the preloaded page.

彼岸花ソ最美的依靠 2024-08-02 00:59:12

关于密码重置:

通过向用户注册的电子邮件地址发送电子邮件来执行此操作的做法虽然在实践中很常见,但安全性并不好。 这样做会将您的应用程序安全性完全外包给用户的电子邮件提供商。 无论您需要多长的密码以及使用任何巧妙的密码散列,都无关紧要。 我将能够通过阅读发送给用户的电子邮件来进入您的网站,前提是我有权访问电子邮件帐户,或者能够在发送给用户的任何地方读取未加密的电子邮件(想想:邪恶的系统管理员)。

这可能重要也可能不重要,具体取决于相关网站的安全要求,但我作为该网站的用户,至少希望能够禁用这样的密码重置功能,因为我认为它不安全。

我发现这份白皮书讨论了话题。

如何以安全的方式执行此操作的简短版本:

  1. 需要有关帐户的确凿事实

    1. 用户名。
    2. 电子邮件地址。
    3. 10 位帐号或其他信息
      例如社会安全号码。
  2. 要求用户至少回答三个预定义的问题(由您预定义,
    不要让用户创建自己的问题),这不是微不足道的。 就像“什么是
    你最喜欢的度假胜地”,而不是“你最喜欢的颜色是什么”。

  3. 可选:将确认码发送到用户必须输入的预定义电子邮件地址或手机号码 (SMS)。

  4. 允许用户输入新密码。

About password reset:

The practice of doing this by sending an email to the user's registered email address is, while very common in practice, not good security. Doing this fully outsources your application security to the user's email provider. It does not matter how long passwords you require and whatever clever password hashing you use. I will be able to get into your site by reading the email sent out to the user, given that I have access to the email account or am able to read the unencrypted email anywhere on its way to the user (think: evil sysadmins).

This might or might not be important depending on the security requirements of the site in question, but I, as a user of the site, would at least want to be able to disable such a password reset function since I consider it unsafe.

I found this white paper that discusses the topic.

The short version of how to do it in a secure way:

  1. Require hard facts about the account

    1. username.
    2. email address.
    3. 10 digit account number or other information
      like social security number.
  2. Require that the user answers at least three predefined questions (predefined by you,
    don't let the user create his own questions) that can not be trivial. Like "What's
    your favorite vacation spot", not "What's your favorite color".

  3. Optionally: Send a confirmation code to a predefined email address or cell number (SMS) that the user has to input.

  4. Allow the user to input a new password.

遥远的绿洲 2024-08-02 00:59:12

我总体上同意您的观点,并提出以下建议的一些修改。

  1. 用户在您的网站上注册并提供电子邮件。
  2. 验证电子邮件将发送到用户帐户,其中包含两个链接:
    a) 一个带有 GUID 的链接,用于验证注册 b) 一个带有 GUID 的链接,用于拒绝验证
  3. 当他们通过电子邮件访问验证 URL 时,他们会被自动验证,并且验证 GUID 会在您的系统中进行标记。
  4. 当他们访问电子邮件中的拒绝网址时,他们会自动从可能的验证队列中删除,但更重要的是,您可以告诉用户您对电子邮件注册感到抱歉,并为他们提供更多选项,例如从系统中删除他们的电子邮件。 这将停止任何关于有人在您的系统中输入我的电子邮件的自定义服务类型的投诉......等等等等。

是的,您应该假设当他们单击验证链接时,他们就已通过验证。 让他们单击页面中的第二个按钮有点多,并且仅在您计划向注册者发送垃圾邮件的样式注册中进行双重选择时才需要。 标准注册/验证方案通常不需要这样做。

I generally agree with you with some modification suggested below.

  1. User registers at your site providing an email.
  2. Verification email is sent to the users account with two links:
    a) One link with the GUID to verify the registration b) One link with the GUID to reject the verification
  3. When they visit the verification url from their email they are automatically verified and the verification guid is marked as such in your system.
  4. When they visit the rejection url from their email they are automatically removed from the queue of possible verifications but more importantly you can tell the user that you are sorry for the email registration and give them further options such as removing their email from your system. This will stop any custom service type complaints about someone entering my email in your system...blah blah blah.

Yes, you should assume that when they click the verification link that they are verified. Making them click a second button in a page is a bit much and only needed for double opt in style registration where you plan to spam the person that registered. Standard registration/verification schemes don't usually require this.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文