在 SRC 里,越权大概是投入产出比最高的一类漏洞。不需要特殊工具,不需要绕过 WAF,会改数字就行。
但它也是扫描器永远发现不了的一类。原因很简单:扫描器不知道”这条数据属于谁”。
SQL 注入有 payload 特征,XSS 有反射点,越权什么都没有——它就是一次完全正常的请求,只不过请求里的 ID 换成了别人的。
扫描器的盲区在哪
所有自动化工具判断漏洞,靠的是”输入触发了异常输出”。注入让数据库报错,XSS 让脚本执行,路径穿越读出 /etc/passwd,都有明确的信号。
越权没有信号。你请求 /api/order/1002,服务器返回 200 和一份订单详情,格式正确、字段完整、没有任何异常。唯一的区别是:这份订单不是你的。
要判断”是不是你的”,工具得知道当前登录用户是谁、这份数据归属谁、两者是否匹配。这三件事都在业务逻辑里,扫描器一概不知。
所以越权只能人工测,而且必须用两个账号对照。一个账号自己测自己,永远测不出来。
三类,测法不一样
| 类型 | 本质 | 典型测试点 |
|---|---|---|
| 水平越权 | 同角色,跨用户 | 订单号、用户 ID、文件 ID、消息 ID |
| 垂直越权 | 低权限访问高权限功能 | 后台接口、管理接口、审核接口 |
| 未授权访问 | 根本不用登录 | 接口漏了鉴权中间件 |
水平越权最常见,也最好挖。找所有带数字 ID 的请求,用自己的账号发一次,把 ID 改成别人的,看返回什么。
关键在于怎么拿到”别人的 ID”。这一步往往比越权本身难。有时候它出现在列表页的响应里,有时候在分享链接里,有时候会被前端加密。
垂直越权的入口通常藏在 JS 里。前台页面看不到后台菜单,但接口路径写在前端代码里,或者全站共用一个 /api/admin/* 前缀。用低权限账号直接请求,看是不是 403。
未授权访问最好找也最容易被忽略:退出登录,把之前抓到的请求重放一遍。返回 200 就是洞。
几个具体手法
改 ID 是最基础的。但直接改数字经常失败,因为很多系统用了自增 ID 之外的方案。这时候换个思路:
改参数名。前端传 userId=1001,后端可能同时接受 uid、user_id、id。加一个参数试试,有些框架会自动绑定。
删参数。把 userId 整个删掉,看后端是不是从 session 里取值。如果返回的数据变了(变成当前用户自己的),说明后端有兜底;如果报错或者返回了别人的,说明它依赖前端传值。
换 HTTP 方法。GET 有鉴权、POST 没有,是常见的不一致。同一个接口用 PUT、DELETE 再试一遍。
改 Content-Type。JSON 转表单、转 XML,有些框架的鉴权中间件只对特定类型生效。
看子资源。主接口校验了归属,但 /order/1002/items 这种子路径经常漏。同样,导出、打印、分享、预览这些”附加功能”最容易漏鉴权。
怎么判断”真的越权了”
返回 200 不等于有洞。有三种情况要分清:
一、返回了别人的数据。最直接。看响应里的用户名、手机号、地址,是不是你自己账号的。不是,就是洞。
二、返回 200 但内容为空。可能是后端做了归属过滤,查不到就返回空数组。这种情况不是洞,但说明接口没有返回 403,值得继续试其他 ID 或子路径。
三、返回 403 但操作生效了。最阴的一种。前端显示”无权限”,但后端已经执行了删除/修改。验证方法是操作后用原账号查一次,看数据还在不在。
批量测试:两个账号 + 一份 diff
手工一个个试太慢。我的做法是准备两个账号(A 是自己的,B 是另一个),然后用工具把 A 的所有请求打到 B 的 token 上,对比响应。
关键是记录三件事:请求路径、A 的响应长度、B 的响应长度。长度接近但不完全一样,往往就是”查到了不同的记录”,值得人肉看。
这一步不用写复杂脚本,Burp 的 Autorize 插件就是干这个的:配置一个低权限 cookie,它会自动把每个请求用这个 cookie 重放,然后标红那些”本来该被拦但没被拦”的。
但要注意:Autorize 只能告诉你”没被拦”,不能告诉你”泄露了什么”。标红的请求还得人肉看响应。
写报告:别写”可导致数据泄露”
SRC 审报告的人每天看几十份,最烦的就是影响描述全是套话。
“攻击者可越权获取其他用户信息,造成严重数据泄露” —— 这句话没有任何信息量。
换成这样:
“使用 A 账号(user_id=1001)请求 GET /api/order/1002,返回了 B 账号的完整订单,包含收货人姓名、手机号、详细地址、下单商品。该接口为自增 ID,遍历 1000-2000 可批量获取约 1000 条真实订单。”
区别在于:具体的接口、具体的字段、具体的量级、具体的遍历成本。审核的人一眼就能判断危害等级。
还有一点,复现步骤要能让别人照着跑通。我见过报告里只写”修改订单 ID 可实现越权”,连是哪个请求都不说。
为什么这类漏洞修不完
因为它不是技术问题,是设计问题。
SQL 注入有标准解法:参数化。XSS 有标准解法:转义。越权没有——每个接口的资源归属关系都不一样,必须一个个想清楚”这个数据属于谁、谁能看”。
更麻烦的是它容易被遗漏在新增功能里。主流程上线前测过了,三个月后加了个导出功能,忘了加鉴权。这种补丁永远打不完。
能做的只有两件事:一是把归属校验收进统一的中间件,让开发者没机会忘;二是把”新增接口必须过越权测试”写进流程。
顺带说一句:别指望前端校验。前端隐藏菜单、隐藏按钮,改个请求就绕过了。所有校验必须在服务端做。
最后
这类漏洞有个特点:挖的时候觉得自己很厉害,修的时候发现满地都是。
如果你在测自己的系统,建议从一个具体功能开始——比如订单列表——把所有相关接口列出来,逐个问一句”这个接口怎么判断数据是不是当前用户的”。答案含糊的,基本都有问题。
比跑一遍扫描器有用得多。
本文仅讨论自有系统与书面授权范围内的安全测试。对未授权系统进行越权测试属于违法行为,与技术水平无关。
- 1、本网站名称: 星宇安全实验室
- 2、本站永久网址:https://bk.zhaozhiqiang.pw/
- 3、本网站的文章部分内容可能来源于网络,仅供大家学习与参考,如有侵权,请联系站长进行删除处理。
- 4、本站一切资源不代表本站立场,并不代表本站赞同其观点和对其真实性负责。
- 5、本站一律禁止以任何方式发布或转载任何违法的相关信息,访客发现请向站长举报
- 6、本站资源大多存储在云盘,如发现链接失效,请联系我们我们会第一时间更新。
- 7、文章版权归作者所有,未经允许请勿转载。













暂无评论内容