越权漏洞命门在于“谁调用、调了谁、有没有校验归属”;须重点检查id、userId等参数是否由前端传入且服务端未二次绑定主体,验证时保持Token不变仅替换ID,确认响应是否返回非当前用户数据。

直接查接口本身,而不是等它出事后再翻日志——越权漏洞的命门在“谁调用、调了谁、有没有校验归属”这三个点上。
怎么看接口是否暴露敏感参数
暴露不等于有漏洞,但暴露是越权的前提。重点盯 id、userId、orderId、tenantId、providerId 这类参数是否由前端传入且未被服务端二次绑定主体。
- 抓包看请求 URL 和 Body:比如
/api/v1/order/12345或{"orderId": "67890"},如果 12345/67890 是纯数字或有序字符串(如雪花 ID 前缀一致),大概率可枚举 - 检查响应体是否返回非当前用户数据:比如登录用户 A,请求
/api/v1/user/2却返回用户 B 的手机号、邮箱、地址 - 留意文档或 Swagger 中是否明文列出“支持任意
id查询”,这是危险信号
怎么验证是否存在水平越权
水平越权的本质是“同权限用户之间数据没隔离”,验证方式就是换 ID 不换 Token。
- 用自己账号登录,获取一个合法
orderId(比如 1001)和对应 Token - 保持 Token 不变,把请求里的
orderId换成 1002、1003……观察是否能成功返回其他用户订单详情、状态、收货地址 - 特别注意分页接口:
/api/v1/comments?offset=0&limit=20,改offset可能翻出别人评论;若接口还带userId参数,更要试userId=2是否绕过校验 - 别只测 GET,DELETE 和 PUT 同样危险——比如
DELETE /api/v1/comment/555成功删掉别人评论,就是实锤
为什么加了 Token 还会越权
Token 只证明“你是谁”,不等于“你能动谁的数据”。很多系统在校验时漏掉了“数据归属”这层判断。
立即学习“前端免费学习笔记(深入)”;
- 典型错误写法:
if (token.isValid()) { findOrderById(params.id); return order; }—— 完全没查这个order归属哪个用户 - 正确姿势必须带双条件:
findOrderByIdAndUserId(params.id, currentUser.getId()),或者查询后显式比对order.getUserId().equals(currentUser.getId()) - 注意关联数据:比如修改订单收货人,
updateOrderAddress(orderId, addressId),这里addressId也得校验是否属于当前用户,否则可能篡改他人地址 - 租户场景更复杂:SaaS 系统中
tenantId必须全程透传并参与 where 条件,不能只在登录态里存着不用
哪些地方最容易被忽略
越权漏洞常藏在“看起来很安全”的环节里,比如导出、统计、批量操作这类辅助功能。
-
/api/v1/export?reportType=sales&date=2026-08:看似只是导报表,但如果后端没校验该租户是否有权查这个时间范围的销售数据,就可能导出全平台数据 -
/api/v1/batch/status?ids=1001,1002,1003:批量查状态,ids 列表若未经校验,可能混入他人 ID - 文件下载接口:
/download?fileId=abc123,fileId 若映射到服务器路径或数据库记录,而没校验所属用户,就会导致任意文件读取 - 前端隐藏 ≠ 后端屏蔽:有些页面按钮灰掉、菜单不显示,但只要 URL 可访问、接口未鉴权,照样能调通
真正难防的不是 ID 暴露,而是“校验逻辑写在前端”或“校验只做一次、漏掉关联字段”。每次看到带 ID 的接口,第一反应不该是“它有没有认证”,而是“它查出来的数据,是不是一定属于当前这个人”。



















