任意密码重置

 人参与 | 时间:2026-10-17 07:30:14

去年秋天,任意我帮一个做独立开发的密码朋友看他的后台系统。登录页长得挺正常,重置但翻到重置密码那块,任意我愣住了——输入邮箱后,密码页面直接跳转到一个带token的重置链接,token是任意一串明文的用户ID加时间戳。我试着把ID改成隔壁测试账号的密码数字,页面刷新,重置新密码框弹了出来。任意整个过程不需要邮箱验证,密码不需要旧密码,重置不需要任何东西。任意两分钟,密码我拿到了他系统里任何一个账号的重置控制权。

这不是个例。任意密码重置漏洞,说白了就是系统在“证明你是你”这个环节偷了懒。最常见的三种翻车姿势:第一种,重置凭证可预测——token用base64编码用户ID,或者干脆就是MD5(用户ID),攻击者改一个字符就能重置别人的密码。第二种,验证码与账号解绑——短信验证码发到A手机号,但提交时只校验验证码对不对,不校验这个验证码属不属于当前要重置的账号。第三种,响应泄露——请求重置时,系统返回“该邮箱不存在”或“邮件已发送”,前者直接暴露用户是否注册,后者配合可枚举的token就能批量操作。

我见过最离谱的一个案例,某电商平台的重置接口长这样:/api/reset?phone=138xxxx&code=1234。你猜怎么着?code参数写死为1234就能通过。开发人员大概觉得“反正前端会校验”,但HTTP请求又不走前端。这种思维在中小型项目里特别常见——把安全逻辑放在客户端,服务端裸奔。

还有一种隐蔽的:重置链接里的token有效期太长。有次我测试一个系统,重置链接三天内有效,而且同一个token可以反复使用。这意味着只要攻击者拿到一次链接(比如从浏览器历史、代理日志、甚至肩窥),就能永久控制那个账号。更骚的是,有些系统在密码重置成功后不失效token,用户改完密码,旧链接还能再改一次。

怎么防?别搞那些花里胡哨的。第一,重置凭证必须用加密随机数生成,长度至少32字节,服务端存储哈希值,用完即焚。第二,验证码和账号强绑定,提交时同时校验手机号/邮箱与验证码的对应关系。第三,所有重置请求的响应统一化——不管邮箱存不存在,都返回“如果账号存在,邮件已发送”。第四,token有效期压到15分钟以内,且单次有效。第五,重置成功后强制下线所有会话。

但说实话,技术方案再完美,也架不住开发图省事。我见过一个团队,明明用了JWT做重置token,结果签名密钥是硬编码的“secret”。攻击者拿到源码后,自己就能签发任意用户的token。安全这玩意儿,短板永远在人身上。你写代码时多问一句“如果我是攻击者,我会怎么绕”,比堆十层防护都管用。

最后提一嘴:别以为小系统没人盯。自动化扫描器每天在互联网上爬,专门找/reset?user_id=这种接口。我那个朋友后来跟我说,漏洞修完第二天,日志里就出现了十几个来自不同IP的探测请求。你看,猎人一直都在。

顶: 91534踩: 63542