权限访问控制缺失 (Broken Access Control)
Published: Sat Feb 01 2025 | Modified: Fri Feb 06 2026 , 2 minutes reading.
1. 定义
权限访问控制缺失 (Broken Access Control) 允许攻击者绕过授权,以特权用户(管理员)或其他用户的身份执行任务。
在 2021 年 OWASP Top 10 中,它目前高居 第 1 位。 它涵盖了:
- 垂直越权: 普通用户获得了管理员权限。
- 水平越权: 用户 A 访问了用户 B 的数据(详见 IDOR 章节)。
- 控制绕过: 直接访问 API 端点而跳过 UI 界面中的权限检查。
2. 技术原理
访问控制的设计决策必须在代码中得到强制执行。漏洞通常产生于:
- “基于隐蔽的安全性”: 虽然在 UI 界面中隐藏了“管理员”按钮,但
/api/admin/deleteUser这个 API 端点却是任何人都能访问的。 - 缺乏全局策略: 开发者只在某些控制器中手动添加了检查,却在另一些地方遗忘了。
- 信任客户端状态: 依赖浏览器发送的数据(如
<input type="hidden" name="role" value="user">)来告知服务器该用户的角色。
3. 攻击流程 (垂直越权)
sequenceDiagram
participant Attacker as 攻击者
participant API
participant DB as 数据库
Attacker->>API: POST /login (身份: 普通用户)
API-->>Attacker: 200 OK (Token 标识: role=user)
Note over Attacker: 攻击者猜到了管理员 URL
Attacker->>API: DELETE /users/555
Note right of API: 代码只检查了用户是否登录。<br/>但忘记检查其角色是否为“管理员”。
API->>DB: 删除用户 555
DB-->>API: 执行成功
API-->>Attacker: 200 OK (用户已删除)4. 真实案例:Facebook “View As” 漏洞 (2018)
目标: Facebook。 漏洞类别: 复杂的访问控制逻辑失效。 影响: 5000 万个账号受到威胁。
逻辑缺陷: Facebook 曾有一个“以…身份查看 (View As)”功能,允许用户查看自己的个人资料在他人眼中是什么样的。 该功能与“视频上传器 (Video Uploader)”功能产生了意想不到的交互:
- 当用户 A 使用“以…身份查看”来查看用户 B 时,视频上传器错误地为用户 B(被查看者)生成了 访问令牌 (Access Token),而不是为用户 A(操作者)生成。
- 访问控制逻辑未能在此特定的功能交互中正确切换上下文。
- 攻击者利用这些令牌可以完全接管受害者的账号。
教训: 功能间的复杂交互往往隐藏着单元测试难以覆盖的权限漏洞。
5. 深度防御策略
A. 默认拒绝 (集中式策略)
不要指望开发者能记住在每个地方添加 isAdmin() 检查。
架构设计: 使用集中式的中间件或 API 网关,默认拒绝所有访问,除非存在特定的角色。
// 安全模式示例 (Node.js) router.use('/admin', requireRole('ADMIN')); // 强制应用于所有 /admin 路由
B. 基于模型的访问控制
在数据模型层而不仅仅是控制器层实施权限控制。
- 即使控制器层漏掉了检查,数据库访问层 (DAL) 如果发现当前用户上下文缺乏相应权限,也应拒绝执行删除等操作。
C. 绝不信任客户端状态
永远不要接受来自客户端 Body 或 Cookie 中未经加密签名的 role、isAdmin 或 pricing 等参数。始终在服务器端通过会话或数据库查询用户的实际权限。
D. 集成测试
编写专门针对负向授权的测试用例:
- “确保普通用户无法访问管理员路由”(应返回 403)。
- “确保用户 A 无法编辑用户 B 的资料”。
