什么是越权漏洞?水平越权和垂直越权有什么区别?
简化版
越权漏洞是指用户能访问或操作本无权限的资源。分两种:水平越权——访问同级别其他用户的数据(如把 URL 里的 id 改成别人的,就看到别人的订单);垂直越权——低权限用户使用了高权限功能(如普通用户直接调用管理员接口)。根源是后端只认「登录了」却没校验「这个资源/操作到底该不该由你来」。防范核心:每次访问都在后端做严格的权限和归属校验。
详细版
水平越权(横向):同一角色的用户之间,A 访问了 B 的数据。典型场景:
你的订单:GET /order?id=1001 (id=1001 是你的)
越权: GET /order?id=1002 (把 id 改成别人的,就看到了别人的订单)
后端只验证了「你登录了」,却没验证「id=1002 这个订单是不是属于你」——这就是水平越权,也叫 IDOR(不安全的直接对象引用)。
垂直越权(纵向):低权限用户获得了高权限操作。典型场景:
管理员功能:POST /admin/deleteUser (本应只有管理员能调)
越权: 普通用户直接构造这个请求调用,后端没校验角色,就删了用户
后端把「管理员按钮不显示给普通用户」当成了防护,但接口本身没做角色校验——普通用户绕过前端直接调接口就越权了。
防范核心:权限校验必须在后端、且针对每一次访问——校验「当前用户是否有权限执行这个操作」+「这个数据是否属于当前用户」。
完整版教学
一、越权的本质:认证 ≠ 授权
越权漏洞的根源,是把认证(你是谁)和授权(你能做什么)混为一谈(详见「认证和授权的区别」那道题):
- 很多系统在用户登录后就放松了警惕——只要带着有效的登录态(token/session),就认为「合法用户」,然后不再检查具体操作的权限;
- 但「登录了」只证明你是某个用户,不代表你有权访问这个特定资源、执行这个特定操作。
越权漏洞就发生在这个缝隙里:认证通过了,但授权没做或做得不到位。所以防御的核心是——每一次访问,除了验证身份,还要验证权限。
二、水平越权:改个 ID 就看别人数据
水平越权(IDOR)是最常见、也最容易被忽视的越权:
- 系统用一个「直接对象引用」(如订单 id、用户 id、文件名)来定位资源;
- 后端根据这个 id 查数据返回,却没校验这个资源是不是属于当前登录用户;
- 攻击者只要把 id 换成别人的(
1001→1002),就拿到了别人的数据。
它的危险在于极其简单——改个数字就行,不需要任何技术。修复的关键是数据归属校验:查询时不能只 WHERE id = 1002,而要 WHERE id = 1002 AND owner_id = 当前用户id——把「资源属于当前用户」作为查询/操作的必要条件。
三、垂直越权:普通用户干管理员的活
垂直越权是「低权限用户执行了高权限操作」:
- 系统区分了角色(普通用户 / 管理员),但只在前端隐藏了高权限功能的入口(不显示管理员按钮);
- 攻击者绕过前端,直接构造请求调用高权限接口(
/admin/xxx); - 如果后端接口没有校验调用者的角色,操作就成功了。
核心误区是**「前端隐藏 ≠ 后端防护」。前端不显示按钮只是「看不见」,接口还在那里、能被直接调用。修复的关键是后端对每个高权限接口做角色/权限校验**——不管前端显不显示,后端都要问一句「你这个角色有权调这个接口吗」。
四、为什么「前端控制」永远靠不住
这是越权(乃至所有 Web 安全)的铁律:前端的一切都可以被绕过。
- 前端的按钮隐藏、表单校验、页面跳转,都运行在用户可控的浏览器里;
- 攻击者可以用 Postman/curl 直接构造请求,完全不经过你的前端页面;
- 所以任何安全校验都必须在后端做,前端的隐藏/禁用只是「用户体验」,不是「安全防护」。
把这句话刻进脑子:安全校验必须在后端,前端控制形同虚设。
五、系统性防御:统一的权限框架
零散地在每个接口手写权限校验容易遗漏(漏了一个接口就是一个漏洞)。工程上要统一、集中地做权限控制:
- 统一鉴权拦截:用拦截器/中间件/AOP 在请求进入业务前统一校验身份和权限,而非散落在各处;
- RBAC(基于角色的访问控制):定义角色和权限,接口声明所需权限,框架自动校验;
- 数据权限(归属校验):在数据层面强制「只能操作属于自己(或授权范围)的数据」;
- 默认拒绝:没有明确授予权限就默认拒绝,避免「忘了加校验就等于放行」;
- 最小权限:每个角色只给必需的权限。
六、常见误区
- ❌ 以为「登录了」就够——登录是认证,还要授权(校验这次操作/资源的权限)。
- ❌ 靠前端隐藏按钮防垂直越权——接口能被直接调用,必须后端校验角色。
- ❌ 查数据只按 id 不校验归属——导致水平越权(IDOR),要加
AND owner=当前用户。 - ❌ 零散手写校验容易漏——用统一鉴权框架 + 默认拒绝,避免漏接口。
六、常见误区与追问
| 考点 | 正确口径 |
|---|---|
| 水平越权 | 同角色用户访问彼此资源 |
| 垂直越权 | 低权限用户执行高权限操作 |
| 防护核心 | 服务端基于主体、资源、动作统一鉴权 |
GET /orders/1001
bad: only check user is logged in
good: check order.ownerId == currentUser.id
admin action: require role/permission explicitly
越权漏洞的本质是“知道资源 ID”被误当成“有权访问资源”。
- 误区:URL 不暴露入口就安全。 攻击者可以直接构造请求,安全不能依赖前端路由隐藏。
- 误区:只校验登录态就能防越权。 登录态只能证明是谁,还必须校验该用户是否能访问该资源。
- 误区:自增 ID 才会越权,UUID 就不会。 不可猜 ID 能降低枚举风险,但不能替代服务端授权。
- 追问:水平越权如何测试? 用用户 A 登录后访问用户 B 的资源 ID,看服务端是否拒绝。
- 追问:垂直越权如何测试? 低权限账号直接调用高权限接口或篡改角色参数,看是否成功。
- 追问:工程上怎么收口? 使用统一鉴权中间件/策略引擎,避免每个接口手写散落判断。
七、加强记忆
越权漏洞是用户访问/操作了本无权限的资源,根源是「认证通过后没做授权校验」。水平越权:访问同级别其他用户的数据(改 id 看别人订单,即 IDOR),修复靠数据归属校验(AND owner=当前用户);垂直越权:低权限用户调高权限接口(绕过前端隐藏),修复靠后端角色校验。铁律是安全校验必须在后端、每次访问都做,前端控制形同虚设;工程上用统一鉴权框架 + RBAC + 默认拒绝。