游客发表

任意密码重置漏洞

发帖时间:2026-10-17 04:37:31

去年某电商平台被曝出一个漏洞:用户在找回密码页面输入自己的任意手机号,抓包把手机号改成别人的密码,验证码竟然发到了自己手机上。重置然后输入自己收到的漏洞验证码,系统直接让重置那个人的任意密码。整个流程不需要任何社会工程学,密码不需要猜密保问题,重置纯粹是漏洞逻辑漏洞。

这就是任意典型的任意密码重置。它不是密码靠暴力破解,也不是重置靠数据库泄露,而是漏洞系统在验证身份时搞错了对象。

漏洞长什么样

最常见的任意场景是三步:第一步,你提交自己的密码账号,系统发验证码给你;第二步,重置你收到验证码,提交验证;第三步,系统让你设置新密码。问题出在第二步和第三步之间——系统没有把“验证通过的这个人”和“要改密码的那个账号”绑定在一起。

攻击者只需要在第一步填自己的手机号,第二步抓包把请求里的用户ID改成受害者的,第三步提交新密码。系统一看验证码对了,用户ID也对得上,直接放行。它不知道验证码是发给攻击者的。

还有一种变体更隐蔽。某社交App的密码重置接口接受一个email参数和一个token参数,token校验通过后,系统根据email字段来定位用户。攻击者用自己的邮箱走完验证流程拿到token,然后把email换成受害者的。token是真的,邮箱也是真的,但两者根本不是一对。

为什么这种漏洞反复出现

开发人员习惯把“验证”和“操作”拆成两个独立接口。验证接口只负责判断验证码对不对,操作接口只负责改密码。两个接口之间靠客户端传来的用户标识来关联。这个用户标识可以是手机号、邮箱、用户ID,随便什么都行,只要攻击者能改。

根本原因在于:系统信任了客户端。它默认客户端在验证通过后,会老老实实传回同一个账号。但抓包工具一开,这个假设就碎了。

我见过一个更离谱的案例。某网站重置密码时,验证码是四位数字,没有次数限制。攻击者直接写脚本从0000试到9999,十分钟内必然爆破成功。这甚至不算逻辑漏洞,但配合任意用户ID的替换,效果一样——想改谁的就改谁的。

怎么防

核心原则只有一条:验证和操作必须在同一个会话里完成。服务端在验证通过后,应该生成一个一次性的、绑定目标用户的凭证,而不是让客户端传用户ID过来。

具体做法:用户提交重置请求时,服务端生成一个reset_token,和用户ID一起存进数据库。验证码校验通过后,把reset_token标记为已授权。最后改密码时,只认这个reset_token,从数据库里反查用户ID。客户端传什么用户标识都不好使。

另外,验证码要限制尝试次数,最好五分钟内超过五次就作废。手机号和邮箱在传输过程中不要明文出现在URL里,用POST。如果业务允许,重置密码后强制下线所有设备,并给用户发通知。

这类漏洞的测试成本极低,一个Burp Suite加上十分钟就能试出来。但修复成本同样低,无非是多写几行服务端代码。问题在于,很多团队在开发时根本没意识到“验证”和“操作”之间需要一个不可篡改的绑定关系。

我个人的判断是:任何让客户端传用户ID来定位账号的接口,都值得重点看一眼。尤其是密码重置、绑定手机、修改邮箱这类敏感操作。抓包改个参数就能得手的东西,不应该出现在2024年的线上系统里。

    热门排行

    友情链接