功能级越权是什么
功能级越权(又叫垂直越权)指低权限用户访问到了本应属于更高权限角色的功能,包括管理菜单、管理页面和管理接口。它的根因不是某个参数被篡改,而是服务端没有对『这个角色能不能调用这个功能』做逐接口校验。常见误区是把安全边界放在前端:隐藏菜单、路由守卫、按钮置灰都只是体验设计,只要接口地址可被猜到或从历史版本、前端代码里读出,就能直接调用。
基本信息
| 别名 | 垂直越权 / 功能级访问控制缺失 |
|---|---|
| 根因 | 服务端未按角色校验功能权限,或权限矩阵未覆盖新接口 |
| 判别方式 | 用低权限账号直接请求管理接口,看是否返回数据而非 403 |
| 参考条目 | OWASP Top 10 A01 失效的访问控制 |
典型使用场景
- 新接口上线时核对权限矩阵,确认是否漏配角色限制
- 安全测试用低权限账号遍历管理接口清单,验证是否返回 403
- 把管理功能拆到独立域名或独立网关,与普通业务接口分权分域
- 代码评审时搜索缺少鉴权装饰器或注解的控制器方法
- 第三方集成场景按应用维度授权,避免用管理员令牌代跑普通接口
服务端校验示意(伪代码)
服务端校验示意(伪代码)
# 正确做法:权限校验在服务端,逐接口强制
@app.route('/admin/users/delete', methods=['POST'])
@require_role('admin') # 装饰器/中间件在进入业务逻辑前校验
@require_permission('user:delete') # 资源 + 动作粒度,而非只判登录
def delete_user():
...
# 无效做法:
# 菜单隐藏 -> 直接请求接口即可绕过
# 前端路由守卫 -> 只是用户体验,不是安全边界
# 按钮置灰 -> 抓包重放原请求即可校验落点与效果
| 落点 | 是否有效 | 说明 |
|---|---|---|
| 前端菜单隐藏 | 无效 | 接口地址不变,直接请求即可访问 |
| 前端路由守卫 | 无效 | 仅影响浏览器内导航,抓包可绕过 |
| 控制器装饰器 / 中间件 | 有效 | 在业务逻辑前统一拦截 |
| 网关统一鉴权 | 有效 | 需保证所有接口都经网关,无直连旁路 |
权限模型建议按角色、资源、动作三层建模,并采用默认拒绝:未显式授权的接口一律返回 403,新增接口默认落到拒绝侧。
权限矩阵要跟随功能迭代更新:新接口上线却未配置权限,是这类问题最常见的产生时机,把它写进上线检查单可显著减少遗漏。