我正在构建一个忘记密码的页面。我一直在阅读,许多消息来源建议让用户输入他们的电子邮件地址,然后在数据库中添加一个令牌并向他们发送一个链接,该链接带有作为 GET 变量附加的令牌。
我很好奇为什么该令牌真的是必要的?如果令牌过期,任何有恶意并访问您的电子邮件的人都可以直接返回忘记密码页面并再次输入您的电子邮件以获取新的密码重置链接。
如果有人可以访问您的电子邮件地址,我什至看不到令牌在某个时候过期的意义。为什么我应该在“忘记密码”页面上使用过期令牌?
你可以反过来问这个问题:为什么重置链接应该永远有效?
当我要求密码重置链接时,我会在大约一两个小时内正常使用它。没有任何优势,两年后我可以点击链接时,我可能不会记得甚至存在这样的重置链接。请求新链接很容易。
另一方面,如果将来有人可以访问我的电子邮件帐户,或者可能以某种方式获得了我的电子邮件的备份,那么他可以使用重置链接。能够阅读电子邮件并不一定意味着可以登录到电子邮件帐户。例如办公室里打开的电子邮件客户端,网吧忘记注销,丢失的手机......
令牌本身应确保攻击者无法预测新重置链接的代码。最好使用随机代码,而不是由用户名、当前时间或电子邮件地址等参数生成的代码。
通常可以说,为什么要使用较弱的方案,如果有更强的方案,而编码工作并没有明显困难?
假设有恶意的人想要访问您在 example.org 上的帐户,但无权访问您的电子邮件帐户。还假设 example.org 的“忘记我的密码”算法的令牌不会过期。
如果这个人至少有一半的聪明,他会做他的研究并在 example.org 上设置一个假帐户,然后点击“忘记我的密码”按钮并自己获取一个重置链接以了解这些令牌是如何构建的(至少,它们的格式)。
然后,该人输入您的用户名并单击“忘记我的密码”按钮,该按钮通过电子邮件向您发送一个不会过期的重置链接,但他们并不关心这一点 - 他们知道重置令牌的格式; 因此,他们可以通过增加令牌来强制重置页面,直到他们找到有效的命中。
当然,这种方法在技术上会找到每个尚未完成的重置请求,但也会找到你的。
如果令牌过期,并且在合理的时间限制内,从生成所述令牌到它过期之间的时间量将发生在攻击者能够“猜测”它之前很久。当然,您总是有机会在他们猜测之前看到电子邮件 - 但这远不如添加过期时间 =P