我正在构建一个新的MVC应用程序。 考虑到这个“忘记密码”流程:
1)您输入了一封电子邮件 2)按“发送恢复密码” 3)收件箱中等待电子邮件,按下其中的链接将显示“新密码”屏幕。
在第1阶段,您提供的电子邮件没有任何限制。 (它甚至可能不存在)。
此流程是否存在重大安全漏洞?
答案 0 :(得分:2)
在与问题下的某人讨论时,我想我会继续发布如何使用类似的流程处理密码重置,并指出我们尝试避免恶意的意图。这是我们的流程:
在登录表单上,有一个“忘记密码”链接
在简单的文本框中忘记密码屏幕,您可以在其中输入您的电子邮件地址。在我们的实施中,电子邮件地址是用户名,但只要每个用户的帐户都附有有效的电子邮件地址,就无所谓了。
用户输入电子邮件地址并按“提交”。
IF 电子邮件地址与有效帐户相关联,我们生成GUID,将其存储在密码重置请求表中,并与请求用户帐户关联并设置到期时间30分钟。
IF 电子邮件地址不存在,我们什么都不做。没有电子邮件发送给任何人。
无论电子邮件地址是否正确,我们始终会显示“谢谢,如果您输入的电子邮件地址正确无误,您很快就会收到一封电子邮件,其中包含有关如何重置密码的说明”。这很重要,因为您不希望使用此表单的不良用户尝试发现用户名。
用户收到电子邮件并点击该链接。如果GUID /链接仍然有效,则会将它们带到重置密码屏幕(使用新密码/确认新密码文本框)。如果不是,如果密钥已过期或不存在,我们会显示“此重置密钥不再有效”。
重置后,用户将被重定向到登录界面以登录该应用程序。
希望这会有所帮助。正如其他人所说,使用一种好的方法来生成重置密码链接,不要在链接中使用任何用户识别信息(有人可以猜测,找出你的算法等)。
答案 1 :(得分:0)
您应该使用https作为"新密码"避免有人试图拦截新密码的部分。
确保您生成的链接无论如何都不会对电子邮件进行编码。否则,如果黑客发现该方案,那么他们可以轻松地使用它来生成链接并重置其他用户的密码。我看到有些人在查询字符串中传递了电子邮件或用户名,这很糟糕。确保您在POST请求中完成剩下的工作。
确保链接在特定时间窗口内到期也是很好的。此外,请确保您的系统接受的密码种类有很好的安全限制(最少字符数,字母数字,特殊字符等)。
确保您记录了启动重置请求的IP地址和重置密码的IP地址。
最后,请确保新密码表单中没有任何XSS(跨站点脚本)错误,您还可以通过在表单中使用防伪标记来防止XSRF(跨站点请求伪造)来添加更多保护。有ASP.NET MVC的AntiForgeryToken()辅助方法。
对电子邮件的无限制有点奇怪 - 它可以用来为其他人生成垃圾邮件。你说它在下一阶段得到了解决,所以如果你的应用程序是低调的并且在一个更可靠的环境中使用,例如小型内联网或小型企业社区,则可能没问题。
即使在那里,如果用户在他们的电子邮件中存在拼写错误并且在系统向其他人发送密码重置电子邮件时等待密码重置电子邮件到达,则可能会成为一个大问题。现在,如果这个"其他人"重置您的用户的密码,你有麻烦。因此,您可能还想重新确认该页面上的电子邮件,但如果收到该电子邮件的用户的意图是恶意的,那么也可能会猜到。鉴于此,最好添加检查以确定用户是否存在于第一阶段 - 完全安全。
答案 2 :(得分:0)
In my implementation,当用户在忘记密码屏幕中输入电子邮件(也是帐户的密钥/ ID)时,他会收到一条消息“电子邮件已发送到您输入的电子邮件:”。当然可能会发生帐户被锁定或不存在的情况。因此,您可以发出另一条消息:“帐户被锁定或不存在”。但由于黑客可以“收获”账户,因此风险很大。