「把 URL 裡的 id=124 改成 125,就顯示出了他人的發票」——這就是 IDOR(存取控制缺陷)。本文講解其原理與可靠的防範方法(不會寫出攻擊步驟)。
為什麼會發生
明明「認證(你是誰)」已經通過,卻缺了「授權(這個人是否可以操作它)」時就會發生。認證與授權是兩回事,能登入並不等於可以查看那份資料。
| 常見的疏漏 | 後果 |
|---|---|
| 登入後就直接信任 ID | 改成他人的 ID 就能輕易繞過 |
| 誤以為「介面上不顯示=安全」 | 一旦被直接呼叫 API 就毫無防備 |
| 建立/更新/刪除沒有權限校驗 | 不僅能查看,還能竄改、刪除 |
為什麼會成立(原理)
防禦:在伺服器端每次確認「擁有者與權限」
針對每個物件校驗擁有者與權限(最重要)
在回傳/變更資料的緊前一刻,必須在伺服器端校驗「目前登入的使用者 ID,是否為該物件的擁有者、是否擁有操作權限」。不滿足則拒絕。
預設拒絕(deny by default)
新的端點應以「除明確許可的條件外一律拒絕」為初始狀態,讓漏加校驗時倒向「拒絕」一側,而非「放行」一側。
只查詢「屬於自己的」物件
在查詢語句本身中就帶上擁有者條件(例如:使用者 ID=本人 來篩選)。統一走全應用程式通用的授權輔助函式,杜絕各處的遺漏。
不要把介面控制誤當成防禦
隱藏/不顯示按鈕屬於 UX,而非防禦。要以「API 會被直接呼叫」為前提,只在伺服器端做判斷。隨機 ID 只能作為輔助。
本站的觀點:雖不花俏,但危害極大。用測試來「盯緊」它
IDOR 在技術上很樸素,連程式碼審查也容易漏看。然而「一次點擊就能看到他人全部個人資訊」這類危害規模屬於最高級。正因如此,把「用另一個使用者去存取他人的 ID,是否回傳 403」固化進自動化測試才是更貼近實戰的做法。本站堅持「不靠用戶端的外觀來防守/只在伺服器端做判斷」的原則。授權是「靠機制每次都生效」的東西,關鍵在於不依賴人的注意力。
接下來閱讀
- 術語:CSRF 是什麼(認證與授權的區別)
- 入門:安全超入門 / 免費安全工具
FAQ
QIDOR 會發生什麼?
已登入的使用者,僅靠把 URL 或 API 中的 ID(如 ?id=124)改成另一個值,就能查看、修改、刪除他人的發票、訂單、個人資訊、檔案等。它是 OWASP 中最常見的問題類別(存取控制缺陷)的代表,可怕之處在於無需任何特殊工具就能發生。
Q最主要的防禦是什麼?
就是「在伺服器端每次確認『目前登入的這個使用者,是否可以操作該物件』」。即使 ID 形式正確,也必須校驗它是否為本人所有、是否擁有權限,不滿足則拒絕(預設拒絕)。絕不能只依賴用戶端的介面控制。
Q把 ID 改成 UUID 或隨機值就能防住嗎?
那只是「讓它更難猜」,並非根本對策。一旦 ID 被洩漏或被分享出去就會被輕易繞過。隨機化只能作為輔助,關鍵一定要落在伺服器端的擁有者與權限校驗上。