跳到正文
>_ITDITDWeb 安全平台

安全指南

密码重置的设计缺陷:登录再强也会被接管账户的5种情形与修复方法

即使密码很长、开启了多因素认证,只要“忘记密码?”这条路很弱,攻击者就能绕开登录、通过重置接管账户。本文讲解重置流程实际出问题的5种形态、OWASP 明确提出的要求,以及指南有意留给你自己决定的部分该怎么定。

发布于 2026-09-05 更新于 2026-10-04 最后核实 2026-09-05 2 分钟阅读

“忘记密码?”通向的是一个让不知道密码的人设置新密码的机制。所以它是一条认证路径——而且通常是该服务最弱的那一条。

为什么只加固登录挡不住

通常路径:登录

长密码 · 多因素认证 · 速率限制 · 暴力破解检测

─────── 同一个账户 ───────

另一条路径:密码重置

只要能收到邮件就行 · 常常不要求第二因素 · 令牌强度从外面看不见

重置是与登录分开的另一条认证路径。登录再强,重置流程弱,真正的强度就由它决定。

重置功能是作为方便用户的功能来做的,因此往往没有按认证同等的严格程度来设计和审查。但从功能上说,它把账户的控制权交给了不知道密码的人。它和登录本身属于同一类。

这与我们按入侵方式整理2026年日本事件时的发现一致:**用有效凭据进入,比利用漏洞更常见。**重置流程正是服务通过自己的官方流程签发这种凭据的地方。

它表现出来的5种形态

CWE-640 在实际中的样子
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 安全的方式编码;有效期以几十分钟计;使用后作废;同一账户签发新令牌时让旧令牌失效。数值本身没有三个性质重要——无法猜测、不可重复使用、不会永久有效。

实现顺序

1

让令牌无法猜测(最优先)

用密码学随机源生成,并用 URL 安全的方式编码。不要用通用的随机函数——“看起来随机”和“无法预测”是不同的性质。数据库里保存令牌的哈希值而不是令牌本身,这样即使数据库被读取,也拿不到能直接使用的令牌(理由与密码存储、哈希与加盐相同)。

2

给它设定寿命,并且只能用一次

使用后作废,同时设置时间上的有效期。同一账户签发新令牌时,也让旧令牌失效——忘了这一点,就又回到了第2种形态。

3

绝不用外部输入拼 URL

用配置生成重置链接,或对照可信域名列表进行验证。不要把请求头原样带进邮件里。OWASP 直接点名了这一点。

4

统一响应,并做速率限制

两种情况返回相同的文字和相同的时间,只在账户确实存在时发送邮件。针对自动提交,按账户加上速率限制或 CAPTCHA。用户不会感到不便;从外部看,两种情况无法区分。

5

完成时把收尾做好

重置完成后,让现有会话失效——如果账户已经被接管,这是把攻击者赶出去的唯一办法——并发送密码已被重置的通知(不含密码)。条件允许的话,在重置路径上也要求第二因素,以免重置成为绕过多因素认证的途径。

重置真正依赖的是邮箱

上面这些都做到了,重置的安全性仍然取决于是否只有账户持有人能收到邮件。如果邮箱账户被盗,一个做得好的重置流程反而比粗糙的更可靠地把账户交给攻击者。所以用户这一侧的优先事项也落在同一处:给邮箱账户最强的保护——强且不重复的密码加多因素认证,最好使用通行密钥。这也是服务商一侧的泄露扩散到你身上的途径(主机服务商被入侵时该怎么做)。

从用户这一侧看

  • 收到自己没申请的重置邮件,意味着有人尝试过。不要点链接——自己登录该服务确认(钓鱼邮件看起来一模一样)。
  • 重置后其他设备被登出,说明实现是正确的。重置后仍保留其他会话的服务,让你没有办法切断入侵者。
  • 重置时没有要求第二因素,说明该服务在这条路径上多因素认证可能被绕过。对重要账户值得试一次。
  • 停止重复使用密码,这件事最好交给密码管理器。

本站的看法:把它当作认证功能来做,而不是便利功能

重置流程变弱,不是因为技术上难,而是因为被归错了类。登录由负责认证的人认真去做;“忘记密码?”则被当作客服路径轻描淡写地做出来。这种待遇上的差别就是弱点所在。我们的立场很简单:凡是交出账户控制权的操作都是认证功能——重置、更改邮箱地址、重新登记第二因素、客服人员手动恢复。**强度由最弱的路径决定,而不是最强的。**把你自己服务里所有能到达账户的路径写出来,通常比你想象的要多。

出处(一手资料)

  • OWASP Cheat Sheet Series「Forgot Password Cheat Sheet」— cheatsheetseries.owasp.org(上文列为“明确提出”的要求都来自这份文档;它没有规定令牌长度和有效期时长)
  • MITRE, CWE-640「Weak Password Recovery Mechanism for Forgotten Password」— cwe.mitre.org

接下来阅读

FAQ

Q已经开启了多因素认证,密码重置弱一点还有影响吗?
A

有影响。很多实现在重置路径上不要求第二因素,这种情况下,重置就成了绕过第二因素夺回账户的途径。你要保护的不是登录页面的强度,而是所有能到达账户的路径的强度。重置完成时让现有会话失效,并尽可能在重置路径上也要求第二因素。

Q重置令牌应该多长、有效期多久?
A

OWASP《Forgot Password Cheat Sheet》要求令牌用密码学安全的随机数生成器生成、长度足以抵抗暴力破解、使用后作废——但没有规定具体的字符数或分钟数。这些需要你自己决定。我们的实用默认值:至少128位随机性并用 URL 安全的方式编码、有效期以几十分钟计、使用后作废、同一账户签发新令牌时让旧令牌失效。数值本身没有三个性质重要:无法猜测、不可重复使用、不会永久有效。

Q显示“该邮箱地址未注册”不是更贴心吗?
A

对用户贴心,但也让攻击者可以免费确认哪些邮箱地址在你这里有账户。OWASP 要求无论账户是否存在都返回一致的信息,并让响应时间也保持一致。两种情况显示相同内容,只在账户确实存在时才发邮件——用户不会感到不便,外部也看不出差别。

Q作为用户能做什么?
A

收到自己没有申请的重置邮件,意味着有人试图重置你的账户。不要点链接——自己登录该服务,确认密码没有在其他地方重复使用、多因素认证已开启。还要记住重置真正依赖的是什么:你的邮箱。能读你邮件的人,就能接连重置你许多账户的密码。请给邮箱账户最强的保护。