本文目录导读:

API安全中检测越权(通常指水平越权和垂直越权)是防护的重中之重,越权漏洞通常因为缺乏对用户身份的细粒度校验,或依赖不可信的客户端输入(如用户ID)。
以下是系统化的检测方法和实践策略,分为静态分析、动态测试和运行时监控三个层面。
核心概念回顾
- 水平越权:用户A(普通用户)能访问用户B(普通用户)的资源。
GET /api/order/123,用户B也能访问用户A的订单123。 - 垂直越权:普通用户能访问管理员接口,普通用户调用
POST /api/admin/deleteUser。
检测方法
静态代码分析与设计审查(左移,最根本的预防)
在代码层未运行时就发现逻辑缺陷。
- 审查鉴权注解:
- 检查是否有全局鉴权拦截器(如Spring Security、自定义Filter),如果接口少了
@PreAuthorize或自定义注解,就是高危。 - 确认“免鉴权接口”列表(如登录、注册、静态资源)是否被严格控制,避免敏感接口被误放。
- 检查是否有全局鉴权拦截器(如Spring Security、自定义Filter),如果接口少了
- 检查资源ID的传入与校验:
- 反模式:直接从URL、请求体或Cookie中取
userId、orderId,然后直接查询返回。 - 正确模式:从Session、JWT Token中提取当前登录用户ID,与请求中的资源ID进行比对。
- 自动化工具:使用CodeQL、Semgrep等编写规则扫描
findById、findByUserId等方法前的参数是否经过权限检查。
- 反模式:直接从URL、请求体或Cookie中取
动态渗透测试(黑盒与灰盒测试)
模拟攻击者视角,需要工具配合自动化。
- 工具化扫描(推荐):
- Authmatrix(Burp Suite插件):专门测试权限矩阵,能自动遍历不同角色(用户A、用户B、管理员)对不同接口的访问结果,清晰对比出越权点。
- AutoRepeater / Turbolntruder(Burp插件):批量替换请求中的Cookies(换成其他用户Token)和资源ID(如
/api/user/100改为/api/user/200),观察返回是否成功。
- 手动测试步骤:
- 水平越权测试:
- 登录用户A,抓取查询个人资料的接口:
GET /api/profile?uid=100。 - 将Cookie或Token替换为用户B的。
- 修改参数
uid=101(用户B的ID),看是否能返回用户B的数据。 - 变种:测试修改、删除操作(
PUT /api/order/123,将订单ID改成其他用户的)。
- 登录用户A,抓取查询个人资料的接口:
- 垂直越权测试:
- 登录普通账户,抓取管理员接口:
POST /api/admin/config。 - 关键点:不替换Token,直接重放该请求,看返回是“403 Forbidden”还是“200 OK”。
- 升级测试:尝试使用普通账户的Token调用后台管理系统接口,看是否被拦截。
- 登录普通账户,抓取管理员接口:
- IDOR(缺乏对象级授权)测试:
- 尝试
UUID或复杂ID(如v2_user_1823f),看能否遍历猜解。 - 尝试直接提交其他用户关联的对象ID(如
group_id、company_id)。
- 尝试
- 水平越权测试:
运行时实时检测(API网关与WAF)
在生产环境拦截恶意行为。
- API网关(如Kong、Apigee、阿里云API网关):
- 配置资源访问控制策略:
用户只能访问与自己Token绑定的资源(需网关支持自定义断言)。 - 网关解析JWT中的
sub字段,与请求路径中的/users/{sub}/orders匹配,不匹配则直接拒绝。
- 配置资源访问控制策略:
- Web应用防火墙(WAF)+ 行为分析:
- 规则引擎:检测短时间内对同一接口(如
/api/user/profile)尝试大量不同ID的请求(如?id=1、?id=2、?id=3),触发告警或限流。 - 异常登录检测:一个IP登录多个不同账号(非正常业务场景),可能正在进行越权探测。
- 规则引擎:检测短时间内对同一接口(如
- 自定义审计日志:
- 记录每次请求的:
访问者身份、访问的资源ID、资源所属者ID。 - 离线分析:写PromQL或SQL查询“访问者身份 != 资源所属者ID 且 状态码 20x”的记录,即为可疑事件。
- 记录每次请求的:
实战中的关键难点与解决方案
难点1:复杂的对象嵌套
- 场景:
POST /api/invoice直接传入orderId=123,后端没有检查这个orderId是否属于当前用户,直接开票。 - 检测方法:动态测时,不仅改
userId,还要改关联对象ID(如orderId、companyId)。
难点2:UUID/非自增ID
- 场景:ID是
a1b2c3d4-...,看似不可枚举。 - 绕过:攻击者可能通过注册页面的邀请链接、订单分享功能间接获取他人UUID。
- 检测:即使ID复杂,也要做替换测试(从Burp的HTTP历史中拿到两个不同用户的UUID互相替换)。
难点3:批量操作接口
- 场景:
POST /api/user/batchDelete传{"ids": [1,2,3]}。 - 检测:测试传入包含非自己资源的ID列表,看是否会批量删除或被拒绝。
自动化检测工具推荐
| 工具/框架 | 类型 | 作用 |
|---|---|---|
| Authmatrix (Burp插件) | 动态测试 | 自动化测试权限矩阵,一键检测水平/垂直越权。 |
| AutoRepeater (Burp插件) | 动态测试 | 批量替换Cookie/Token/参数,进行越权重放。 |
| Semgrep / CodeQL | 静态分析 | 扫描代码中是否存在未校验的findById调用。 |
| OpenAPI/Swagger + fuzzing | 自动化测试 | 对API规范中定义的每个接口,尝试不同角色的Token。 |
| 自定义脚本 (Python + requests) | 动态测试 | 针对内部系统写脚本,依次用Token A访问资源B。 |
最佳实践流程
- 设计阶段:强制要求所有接口必须从Token获取用户身份,禁止从前端传入
userId。 - 开发阶段:接入静态代码扫描(Semgrep),自动告警未经授权的资源查询。
- 测试阶段:使用Burp Suite的Authmatrix插件进行自动化越权扫描,作为发布前必须通过的卡点(Gate)。
- 生产阶段:API网关进行基础的身份校验,WAF检测异常ID枚举行为,审计日志定期分析越权尝试。
一句话建议:不要信任任何来自客户端的用户标识或资源ID,始终从服务端安全上下文(如Session、JWT) 中提取当前用户,并坚持最小权限原则。