不安全的直接對象引用 (IDOR)
1. 定義
不安全的直接對象引用 (Insecure Direct Object Reference, IDOR) 發生在應用程式根據用戶提供的輸入(如 URL 中的資料庫 ID)直接提供對對象的存取,但未驗證該認證用戶是否有權存取該特定對象時。
在 OWASP API 安全 Top 10 中,這被歸類為 BOLA (Broken Object Level Authorization, 失效的對象級授權)。
2. 技術原理
假設一個 URL:https://api.site.com/invoices/1001。 後端程式碼可能如下:
app.get('/invoices/:id', (req, res) => {
// 易受攻擊:僅檢查了用戶是否登入,但未檢查其是否擁有發票 #1001
if (!req.session.user) return res.status(401);
const invoice = db.find(req.params.id);
res.json(invoice);
});攻擊者只需將 1001 改為 1002, 1003 等,即可下載系統中的每一張發票。這裡的「直接對象引用」是 ID 1001,「不安全性」則源於缺乏所有權校驗。
3. 攻擊流程
sequenceDiagram
participant Attacker as 攻擊者
participant API
participant DB as 資料庫
Attacker->>API: GET /invoices/1001 (攻擊者自己的 ID)
API->>DB: 查詢 ID 1001
DB-->>API: 返回發票 1001
API-->>Attacker: 200 OK (正常顯示)
Note over Attacker: 攻擊者注意到 ID 是連續的。
Attacker->>API: GET /invoices/1002 (受害者的 ID)
API->>DB: 查詢 ID 1002
Note right of API: 應用程式未能檢查:<br/>「用戶 A 是否擁有發票 1002?」
DB-->>API: 返回發票 1002
API-->>Attacker: 200 OK (數據洩漏)4. 真實案例:First American Financial (2019)
目標: 第一美國金融公司 (First American Financial Corp,大型產權保險商)。 漏洞類別: IDOR / BOLA。 洩漏數據: 8.85 億條記錄。
技術背景: 該公司網站通過如下 URL 結構提供文件圖像: fastweb.firstam.com/documents/view?docId=1234567 存取這些文檔不需要身份驗證(或驗證極弱)。關鍵在於,文檔 ID 是連續遞增的。
攻擊經過: 一名房地產開發商發現,只需在 URL 中更改 ID 即可查看他人的稅務記錄、電匯交易收據和駕照圖像。 這種簡單的遍歷操作讓他能夠存取自 2003 年以來近 10 億條敏感的財務記錄。
影響: 導致了巨大的聲譽損失和監管罰款。這是一個教科書般的案例,展示了簡單的順序 ID 如何導致災難性的洩漏。
5. 深度防禦策略
A. 每次存取都執行授權檢查
這是唯一的根治方法。 絕不假設用戶登入了就有權存取。
邏輯實現:
const invoice = db.find(id); if (invoice.ownerId !== req.session.userId) { throw new ForbiddenError("您無權存取此資源"); }中間件: 使用策略中間件(如 CASL, CanCan)來集中實施「資源所有權」規則。
B. 使用間接或隨機引用 (UUID)
不要在公開 ID 中使用自增整數 (1, 2, 3)。
- UUID: 使用 UUID (如
550e8400-e29b-41d4-a716-446655440000)。它們是不可預測的,無法被遍歷 (Enumeration)。 - 映射表: 在 Session 查找表中將內部 ID (1) 映射到外部隨機令牌 (abc-xyz)。
- 注意: UUID 只能防止「遍歷」,但不能解決根本的權限問題。如果攻擊者通過某種方式拿到了 UUID,且系統缺乏權限驗證,他們依然可以存取。防禦 A 依然是必須的。
C. 自動化測試
IDOR 很難被常規掃描器發現,因為掃描器不理解「業務邏輯」(即誰擁有什麼)。
- 編寫整合測試,明確模擬:以用戶 B 的身份登入,嘗試存取用戶 A 的資源。
