## 访问控制缺陷（Critical）

### 触发信号

- 对象属性从请求参数直接映射到模型（`Object.assign(model, req.body)`、`model.update(req.body)`）
- API 端点操作资源但未校验当前用户对资源的所有权
- 路由/接口未做角色检查（管理员接口可被普通用户访问）
- 批量操作接口（删除多个、更新多个）未逐条校验权限

### 判定流程

1. **检查批量赋值**：`Read` 确认请求参数到模型的映射方式：
   - `Object.assign(user, req.body)` → 用户可传入 `role: 'admin'` 等敏感字段
   - `model.update(req.body)` → 同上
   - 应使用白名单字段（只允许 `name`/`email` 等安全字段）
2. **检查资源级授权（IDOR）**：`find_references` 追踪资源操作函数，确认是否校验当前用户对资源的所有权：
   - 是否查询时过滤了 `userId === currentUser.id`
   - 资源 ID 是否来自用户可控参数（路径参数、查询参数）
   - 批量操作是否逐条校验（而非只校验一次就操作所有）
3. **检查角色/权限**：`Grep` 搜索路由定义，`Read` 确认敏感接口（管理员操作、删除、导出）是否有角色中间件：
   - 是否仅依赖前端隐藏（前端隐藏按钮 ≠ 后端限制）
   - 角色检查是否在中间件中（而非在每个 handler 中手动检查）

### 证据构造

确认缺陷后，输出需包含：
- 缺陷位置（批量赋值/IDOR/缺少角色检查的位置，含文件:行号）
- 攻击向量（修改请求参数提权、篡改 ID 访问他人数据）
- 利用场景（`{ "role": "admin" }`、修改 `/api/users/123` 为 `/api/users/456`）
- 业务影响（权限提升、数据泄露、未授权操作）

### 排除

- 已使用白名单字段过滤（`pick(req.body, ['name', 'email'])`）
- 已有资源所有权校验（查询条件包含 `userId`）
- 已有角色中间件保护敏感接口
- 注意：业务逻辑层面的权限绕过由 logical-defects/authorization-bypass.md 覆盖

### 与逻辑缺陷的关系

本文件聚焦**攻击向量**（如何通过篡改请求参数绕过控制），logical-defects/authorization-bypass.md 聚焦**业务语义**（是否遗漏了权限检查）。两者互补，建议同时检测。
