越权是服务端权限校验缺失导致的业务逻辑缺陷,必须在每个请求中实时校验当前用户身份与资源归属,前端流程控制、参数映射、路由守卫等均无法提供有效防护。

“流程控制逻辑”不能消灭越权隐患,“一一对应的映射”本身也不是越权的解药——越权是权限校验缺失导致的业务逻辑缺陷,不是靠流程编排或参数映射能绕过或掩盖的。
真正起作用的,是每个请求到达后端时,对「当前用户身份」与「所操作资源归属」的实时、强制、不可绕过的校验。所谓“流程控制”,如果指前端跳转顺序、按钮显隐、路由守卫等,这些全部可被跳过,对越权零防护力。
下面说清楚几个关键点:
一、为什么“流程控制”不等于权限控制
- 前端控制的流程(比如“先选商品→再填地址→最后付款”)只是用户体验路径,攻击者可直接构造第三步请求,跳过前两步;
- URL 参数映射(如
/order/{id}→ 对应某用户订单)若没在服务端校验id是否属于当前登录用户,改个id就能看别人订单; - 路由权限、菜单隐藏、按钮禁用,全是客户端装饰,抓包重放即可绕过;
- 所有依赖“用户必须按顺序走流程”来保障安全的设计,本质上都是把权限逻辑错误地交给了前端。
二、真正有效的校验必须落在服务端每一步
对每一个涉及用户私有数据的接口,都要做两件事:
- ✅ 从 session / JWT 中明确提取当前登录用户的唯一标识(如
userId或sub); - ✅ 根据请求参数(如
orderId=123)查数据库或缓存,确认该orderId归属的owner_id等于当前userId; - ❌ 不接受任何来自前端的“声称身份”,如
?userId=xxx、{ "targetUserId": "abc" }等字段直接用于查询; - ❌ 不复用前端传来的 ID 做权限判断依据,除非它已被后端二次绑定并验证过归属。
三、多步流程中特别容易出问题的环节
- 第一步返回了“可编辑的订单列表”,但没过滤仅限本用户的订单 → 攻击者拿到别人订单 ID 后,在第二步直接提交修改;
- “加载草稿”接口返回了全量草稿数据,未按用户隔离 → 可遍历
draftId=1,2,3...扫描他人草稿; - 审批流中,“同意”操作只校验了按钮是否可见,没校验当前用户是否是该审批单的直属上级或指定审批人。
四、推荐落地做法
- 所有读写接口统一接入鉴权中间件,自动注入
currentUserId,并强制要求开发者声明资源归属字段(如@OwnershipCheck(target = "orderId", ownerField = "userId")); - 对高频接口(如状态轮询、配置拉取),确保返回数据已按用户维度过滤,不依赖前端筛选;
- 在日志中记录每次资源访问的
userId+resourceId+action,便于事后审计异常模式; - 自动化测试里加入越权用例:用 A 用户 token 访问 B 用户的资源 ID,预期必须返回 403 或空数据,而非 200 + 数据。
不复杂但容易忽略:越权不是流程没走对,而是根本没查“这个东西是不是你的”。

















