“忘记密码?”通向的是一个让不知道密码的人设置新密码的机制。所以它是一条认证路径——而且通常是该服务最弱的那一条。
为什么只加固登录挡不住
通常路径:登录
长密码 · 多因素认证 · 速率限制 · 暴力破解检测
─────── 同一个账户 ───────
另一条路径:密码重置
只要能收到邮件就行 · 常常不要求第二因素 · 令牌强度从外面看不见
重置功能是作为方便用户的功能来做的,因此往往没有按认证同等的严格程度来设计和审查。但从功能上说,它把账户的控制权交给了不知道密码的人。它和登录本身属于同一类。
这与我们按入侵方式整理2026年日本事件时的发现一致:**用有效凭据进入,比利用漏洞更常见。**重置流程正是服务通过自己的官方流程签发这种凭据的地方。
它表现出来的5种形态
- 1. 可猜测的令牌
- 连续值、时间戳、短字符串,或非密码学的随机数。别人的重置可以通过猜测或暴力破解完成
- 2. 永不失效的令牌
- 没有有效期、用过后仍有效、可重复使用。签发过一次的链接一直能用
- 3. 留在邮箱里的链接
- 能看邮箱的人就能看到重置链接。转发规则、共享账户、离职同事的邮箱——看到邮件的人比你想象的多
- 4. 由外部指定的目标地址
- 如果用请求的
Host头来拼重置 URL,外部提供的值就可能变成你邮件里的链接(Host 头注入) - 5. 暴露账户的响应
- 一句贴心的“未注册”,或响应时间上的差异,会让这个表单变成从外部确认谁有账户的工具(用户枚举)
CWE-640“Weak Password Recovery Mechanism for Forgotten Password(忘记密码时的弱恢复机制)”就是这一类问题的名称。它的定义是:产品“包含一种让用户在不知道原密码的情况下恢复或更改密码的机制,但该机制很弱”。请注意这句话的意思——问题不在于有这个功能,而在于这个功能没有它所能替代的认证那么强。
不要把安全问题当作唯一的途径
OWASP 对安全问题的立场是:不应把它作为重置密码的唯一机制,因为其答案往往很容易被攻击者猜到或获取——同时也指出,与其他方法组合时它可以作为额外的一层。在社交资料和公开记录随处可查的时代,母亲的婚前姓氏并不是秘密。
指南明确要求的,和留给你决定的
这是实现时容易犹豫的地方。请把两者分开。
OWASP 明确提出的
・用密码学安全的随机数生成器生成令牌
・长度足以抵抗暴力破解
・使用后作废
・无论账户是否存在都返回一致的信息
・响应时间也保持一致,防止枚举
・用速率限制、CAPTCHA 或类似控制对付自动提交
・自动让现有会话失效,或询问用户是否失效
・用邮件通知用户密码已被重置——邮件里不要放密码
・拼重置 URL 时不要依赖 Host 头(写死,或对照可信域名列表验证)
・确保 URL 使用 HTTPS
指南没有定下的数值(由你决定)
・令牌的实际长度——只说了“足够长”
・有效期——要求使用后作废,但时间限制没有给出数值
不要把没有数值理解为“这不需要决定”。它需要有理由地决定下来,并写成文档。
我们的实用默认值:至少128位随机性并用 URL 安全的方式编码;有效期以几十分钟计;使用后作废;同一账户签发新令牌时让旧令牌失效。数值本身没有三个性质重要——无法猜测、不可重复使用、不会永久有效。
实现顺序
让令牌无法猜测(最优先)
用密码学随机源生成,并用 URL 安全的方式编码。不要用通用的随机函数——“看起来随机”和“无法预测”是不同的性质。数据库里保存令牌的哈希值而不是令牌本身,这样即使数据库被读取,也拿不到能直接使用的令牌(理由与密码存储、哈希与加盐相同)。
给它设定寿命,并且只能用一次
使用后作废,同时设置时间上的有效期。同一账户签发新令牌时,也让旧令牌失效——忘了这一点,就又回到了第2种形态。
绝不用外部输入拼 URL
用配置生成重置链接,或对照可信域名列表进行验证。不要把请求头原样带进邮件里。OWASP 直接点名了这一点。
统一响应,并做速率限制
两种情况返回相同的文字和相同的时间,只在账户确实存在时发送邮件。针对自动提交,按账户加上速率限制或 CAPTCHA。用户不会感到不便;从外部看,两种情况无法区分。
完成时把收尾做好
重置完成后,让现有会话失效——如果账户已经被接管,这是把攻击者赶出去的唯一办法——并发送密码已被重置的通知(不含密码)。条件允许的话,在重置路径上也要求第二因素,以免重置成为绕过多因素认证的途径。
重置真正依赖的是邮箱
上面这些都做到了,重置的安全性仍然取决于是否只有账户持有人能收到邮件。如果邮箱账户被盗,一个做得好的重置流程反而比粗糙的更可靠地把账户交给攻击者。所以用户这一侧的优先事项也落在同一处:给邮箱账户最强的保护——强且不重复的密码加多因素认证,最好使用通行密钥。这也是服务商一侧的泄露扩散到你身上的途径(主机服务商被入侵时该怎么做)。
从用户这一侧看
- 收到自己没申请的重置邮件,意味着有人尝试过。不要点链接——自己登录该服务确认(钓鱼邮件看起来一模一样)。
- 重置后其他设备被登出,说明实现是正确的。重置后仍保留其他会话的服务,让你没有办法切断入侵者。
- 重置时没有要求第二因素,说明该服务在这条路径上多因素认证可能被绕过。对重要账户值得试一次。
- 停止重复使用密码,这件事最好交给密码管理器。
本站的看法:把它当作认证功能来做,而不是便利功能
重置流程变弱,不是因为技术上难,而是因为被归错了类。登录由负责认证的人认真去做;“忘记密码?”则被当作客服路径轻描淡写地做出来。这种待遇上的差别就是弱点所在。我们的立场很简单:凡是交出账户控制权的操作都是认证功能——重置、更改邮箱地址、重新登记第二因素、客服人员手动恢复。**强度由最弱的路径决定,而不是最强的。**把你自己服务里所有能到达账户的路径写出来,通常比你想象的要多。
出处(一手资料)
- OWASP Cheat Sheet Series「Forgot Password Cheat Sheet」— cheatsheetseries.owasp.org(上文列为“明确提出”的要求都来自这份文档;它没有规定令牌长度和有效期时长)
- MITRE, CWE-640「Weak Password Recovery Mechanism for Forgotten Password」— cwe.mitre.org
接下来阅读
- 防御:如何选择和使用密码管理器 / 密码存储、哈希与加盐
- 术语:什么是双因素认证 / 什么是通行密钥 / 什么是钓鱼
- 滥用防控:速率限制与滥用防控(重置路径的速率限制该放在哪里)
- 趋势:2026年,攻击者更多是带着凭据而不是漏洞利用进来的
FAQ
Q已经开启了多因素认证,密码重置弱一点还有影响吗?
有影响。很多实现在重置路径上不要求第二因素,这种情况下,重置就成了绕过第二因素夺回账户的途径。你要保护的不是登录页面的强度,而是所有能到达账户的路径的强度。重置完成时让现有会话失效,并尽可能在重置路径上也要求第二因素。
Q重置令牌应该多长、有效期多久?
OWASP《Forgot Password Cheat Sheet》要求令牌用密码学安全的随机数生成器生成、长度足以抵抗暴力破解、使用后作废——但没有规定具体的字符数或分钟数。这些需要你自己决定。我们的实用默认值:至少128位随机性并用 URL 安全的方式编码、有效期以几十分钟计、使用后作废、同一账户签发新令牌时让旧令牌失效。数值本身没有三个性质重要:无法猜测、不可重复使用、不会永久有效。
Q显示“该邮箱地址未注册”不是更贴心吗?
对用户贴心,但也让攻击者可以免费确认哪些邮箱地址在你这里有账户。OWASP 要求无论账户是否存在都返回一致的信息,并让响应时间也保持一致。两种情况显示相同内容,只在账户确实存在时才发邮件——用户不会感到不便,外部也看不出差别。
Q作为用户能做什么?
收到自己没有申请的重置邮件,意味着有人试图重置你的账户。不要点链接——自己登录该服务,确认密码没有在其他地方重复使用、多因素认证已开启。还要记住重置真正依赖的是什么:你的邮箱。能读你邮件的人,就能接连重置你许多账户的密码。请给邮箱账户最强的保护。