我正在使用OTP(一次性密码)实现密码重置功能.当用户单击“忘记密码”链接时,会向他/她发送OTP,并将其重定向到OTP输入页面。输入OTP后,用户将被重定向到“update密码”页面。
如何防止任何用户绕过OTP输入页面,直接进入“更新密码”页面?
我知道我可以在数据库中存储OTP输入是有效的这一事实,然后我可以在访问“update密码”页面时检查它。除了这一点,还有什么替代的/首选的方法吗?
这个问题是关于如何在不允许用户绕过任何步骤的情况下最好地实现所需的工作流。这与OTP对攻击的抵抗力无关。
发布于 2019-08-08 04:05:15
您的“更新密码”页面应该包含三个字段:旧密码、新密码和重复新密码。当通过“忘记密码”链接访问时,应该包含OTP输入字段,而不是旧的密码输入字段。如果你能帮上忙的话,你可能不应该通过重定向或别的什么方式来分割它。
发布于 2019-08-08 15:22:16
听起来好像有你想要实现的业务逻辑。具体情况将取决于您在构建web应用程序时所使用的语言或框架。我建议您有您的网页或路线,需要认证(即私人)和那些没有(即公开)。“更新密码”页面是私有的,OTP页面是公共的。这意味着,没有人可以访问更新密码页,除非他们已经过身份验证。
然后,工作流是用户登陆到您的公共OTP页面上。任何人都可以到达那里,任何人都可以进入任何OTP。您的目标用户在OTP中键入。您信任OTP*,因此您相信OTP是一个合适且健壮的身份验证令牌。此时,您的代码(如果您正在使用MVC或其他应用程序)在用户中签名。您知道用户的ID,因为您已经说过要在数据库中记录OTP。
现在,您的用户是一个合法的登录用户,您可以从您的路由重定向到更新密码页。
您并没有说要阻止用户到除更新密码页以外的任何地方,但是如果您想让它成为他们唯一可以去的地方,那么您需要有一个标志,上面写着该用户处于后OTP阶段,然后您的路由将不得不检查这一点,如果用户是后OTP用户,则必须拒绝对任何路由的访问。更新数据库后,您必须重置OTP标志。我不认为我会费心去编写代码以获得边际收益,但如果您想要这样做,您可以签入每个页面,或者如果使用Django,您可以装饰视图函数,或者使用框架提供的任何帮助。
*您确实特别讨论了OTP抵抗攻击的问题,但我认为如果您确实使用OTP作为唯一标识符,那么您应该在OTP页面上询问用户的用户名/电子邮件地址/电话号码,并且应该考虑到OTP是短的(低熵),因此您可能想要防止暴力,然后使用OTP+ UID组合来识别用户。显然,短OTP比长密码更糟糕,因此您需要针对它构建控制,但我不想讨论这些。如果您想直接从“忘记密码”页面返回,那么您可以在“我们已经向您发送了OTP代码(如果有您的详细信息)”确认后重定向,并且您可以使用服务器端变量来确保您知道用户输入的UID,该用户希望重置他们的密码,但是由于忘记密码页是公开的,而且您不能信任该用户,那么我看不出询问UID/电子邮件或甚至将其包括在标头中有什么不利之处。
https://security.stackexchange.com/questions/214907
复制相似问题