游客发表

用户名遍历漏洞

发帖时间:2026-10-17 05:07:18

去年冬天,用户我帮一个朋友查他刚上线的名遍小程序。功能很简单,历漏用户注册后可以设置一个昵称,用户系统会分配一个数字ID。名遍我随手把URL里的历漏ID从1001改成1002,页面直接弹出了另一个用户的用户手机号和收货地址。他愣了三秒,名遍说“这也能行?历漏”

这就是用户名遍历漏洞。攻击者不需要任何技术工具,用户只要把请求里的名遍用户标识改一改,就能像翻抽屉一样把别人的历漏数据翻出来。问题出在服务端——它默认“你传什么ID,用户我就查什么ID”,名遍从不验证这个ID是历漏否属于当前登录的人。

很多人以为这种漏洞只出现在老系统里。错了。我见过一个日活几十万的社交App,它的“查看主页”接口是/user/profile?uid=12345。把uid换成别人的,就能看到对方的私密动态、绑定的邮箱,甚至最近登录的IP。开发团队后来承认,他们觉得“uid是随机的,猜不到”。但uid是自增的,从1开始,遍历成本几乎为零。

更隐蔽的变体是“批量遍历”。有些接口不返回完整信息,只返回一个布尔值,比如“该手机号是否注册”。攻击者用脚本跑一遍号段,就能拿到全量用户名单。这种接口设计本意是给注册页面做实时校验,结果变成了数据泄露的入口。一个做电商的朋友告诉我,他们曾被人用这种方式爬走了二十万条手机号,每条在黑市卖两毛钱。

为什么这种漏洞屡禁不止?根子在于开发习惯。很多后端框架的默认写法就是findById(id),参数直接从请求里取。开发者脑子里想的是“功能跑通”,不是“权限隔离”。等上线后再补,往往只在前端加个隐藏按钮,后端接口照样裸奔。抓包改个参数,防线就没了。

还有一种情况是“以为UUID就安全”。确实,UUID比自增ID难猜,但泄漏渠道太多了。用户分享链接、日志打印、第三方SDK上报,任何一个环节都可能把UUID暴露出去。一旦拿到一个有效的UUID,配合遍历工具,照样能横向扩展。我见过一个系统用UUID做用户标识,但它的“消息已读”接口居然接受任意UUID作为接收者,结果攻击者可以给任何用户发系统通知。

怎么防?最直接的办法是在服务端做两层校验。第一层,从会话里取出当前登录用户的ID,而不是从请求参数里取。第二层,如果业务确实需要查别人的数据(比如查看好友主页),那就显式检查好友关系或公开权限。别偷懒用@RequestParam直接接用户ID,那等于把钥匙插在门上。

另一个实用技巧是给ID加盐。比如用户ID是123,但对外暴露的是123_hmac(123, secret)。服务端收到后先验签,不合法直接拒绝。这样即使攻击者拿到一个合法签名,也无法推导出其他用户的签名。成本很低,但能挡住绝大多数自动化遍历。

我自己的习惯是:任何接受用户标识的接口,写完第一件事就是拿两个账号互相改参数测试。改自己的ID查别人,改别人的ID查自己,看返回是否一致。这个动作花不了两分钟,但能省掉后面一堆麻烦。别信“没人会注意到这个接口”这种话——爬虫和扫描器每天都在全网跑,你的接口迟早会被翻出来。

最后说个真事。某次安全测试,我用Burp跑了一遍目标站点的所有数字参数,从1到5000。结果在一个“下载发票”的接口上,成功下载了四百多张别人的发票PDF。每张PDF里都有公司名、税号、金额。那个接口的URL是/invoice/download?no=10001。开发后来跟我说,他以为发票号是随机的。我回了一句:你猜我跑了多久?三分钟。

    热门排行

    友情链接