越权漏洞扫描扫出来的东西,一大半是误报。听着有点反直觉吧?干久了就见怪不怪了。真正能顺走别人订单号、手机号、收货地址的那种越权,扫描器基本看不见——它手上压根没有第二个账号,没法逐个比对。报告里那一堆标红的“疑似越权”,说白了,还得你自己再过一遍。

越权漏洞扫描能扫到的,多是明面上那几种
扫描器干活的路子笨得很。爬一遍站,把 URL 里的数字参数挨个加一减一,看响应长度变没变;GET 换成 POST 再试一次;Cookie 一删直接敲 /admin/user/list,看是不是还回 200 带一串用户名。就这三招,能抓到的东西有限,但确实抓得到:未授权访问、后台目录裸奔、id=1 改成 id=2 就吐出别人昵称的那种最原始的水平越权。
后台接口没挂鉴权、浏览器地址栏直接能进去的站,我见得不算少。这种扫描一秒就报。
水平和垂直越权,扫描器对哪个更灵
垂直越权好办。拿一个普通用户的 token 去请求管理端接口,返回 200,响应体里又不是”无权限”那类话术,八成就是低权限摸到了高权限的地盘。逻辑单一,规则能覆盖得住。
水平越权就麻烦多了。它得枚举 ID,还得判断返回的那条数据到底是不是别人的。ID 是自增数字,扫描器还能撞一撞;一旦换成 UUID、换成哈希、换成 base64 之后那一长串,它当场就瞎了。你会发现报告里”水平越权”那一栏经常空着,不是站点干净,是它压根扫不动呢。
扫不出来的那部分,才是真麻烦
多步骤的业务流程最要命。下单、改价、支付三个接口串在一起,单独看每一个都规规矩矩,串起来就出事——A 用户能把 B 用户的订单号塞进支付接口,照样付得通。这种状态机式的漏洞,扫描器理解不了。
参数藏在 JSON 嵌套里、藏在加密串里、藏在 GraphQL 的 variables 里,它也扫不到。还有被频率限制挡住的,扫到一半 IP 被封,报告直接断尾,你还以为没漏洞。
所以我一般不看扫描器的”通过率”,那个数字意义不大。
越权漏洞扫描做完,我一般怎么手工复核
开两个浏览器,两个账号,都得是普通用户,别拿管理员凑数。A 账号挂着 Burp 代理,把请求丢进 Repeater,再把 Cookie 换成 B 的,或者把 body 里的 userId 换成 B 的,看返回什么。
命令行也能干,我更常用这个。curl 带 A 的 session 去请求 B 的资源,两个响应体丢一起比字节数:curl -s -H “Cookie: PHPSESSID=xxxx” https://example.com/api/order/1002 | wc -c。长度跟 B 自己请求时一模一样,那就有问题了;要是返回一段”订单不存在”,说明后端做了归属校验,放过。
顺手翻一眼 access.log 也有用,同一个 IP 短时间内用不同 uid 拉走一堆 200,这种痕迹扫描器不会写进报告。
报告里那些「疑似」到底怎么判
三条。
返回 200,响应体里出现别人的字段值;返回长度差异明显;写操作真的落库了。前两条容易误判,有些接口对谁都返一个空对象,长度完全一致,扫描器也当成越权报上来。第三条最硬,但也最危险,只能在测试环境造数据验证,别拿生产库做实验。
单条 200 不算证据。
修的时候别只改一个接口
最常见的情况是这样:扫出来十个接口,开发挨个加 if 判断,改完上线,过两个月新功能一上又漏一遍。根子不在接口,在鉴权是散的,散在几十个控制器里,谁都记不全。
我一般这么整:路由层挂个统一中间件。凡是带业务 ID 的请求,一律从 session 里取当前 uid,再用这个 uid 去查数据。请求里传进来的 userId,只当参数校验,不当查询条件。SQL 那边顺手带上 and user_id = ?。前端隐藏字段、页面上的 disabled、JS 里那点判断,全都不算数。抓包一改就破。
后台那种垂直越权,管理端路由和普通路由分两个中间件栈,别共用一个。提前拦住就好,不然等出事再回头补,代价大得多。
扫描器该跑还是跑嘛,它负责筛掉那批低级的、摆在明面上的问题,省你手工翻目录的功夫。剩下的得靠人。真要确认一个越权,老老实实开两个账号点一遍呗,这事儿没有捷径。
【版权声明】:本站内容若无意侵犯到您的权利,请及时与我们联系将尽快删除相关内容!