權限存取控制缺失 (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 的資料」。
