不安全直接物件引用 (IDOR)

不安全的直接物件引用 (IDOR) 是一種漏洞,它允許攻擊者利用不充分的訪問控制和對物件識別符號(如資料庫金鑰或檔案路徑)的不安全暴露。

網站通常希望為不同的使用者提供不同的內容:例如,購物網站可能允許每個使用者檢視他們的購買歷史記錄。網站可以透過身份驗證來識別使用者,使用密碼或金鑰等方法。通常,一旦網站驗證了使用者身份,它會在使用者的瀏覽器中設定一個會話 cookie:然後,當用戶發出請求時,伺服器就會知道該請求來自該已驗證的使用者。

然而,除了檢查請求是否來自已驗證的使用者之外,伺服器還必須為使用者請求的資源實施訪問控制:也就是說,它們必須檢查該使用者是否允許訪問所請求的特定資源。例如,每個已驗證的使用者只能檢視自己的購買歷史記錄。

如果伺服器沒有為資源實施訪問控制,那麼已登入該網站的攻擊者就可能能夠訪問屬於其他使用者的資料。這就叫做不安全的直接物件引用 (IDOR) 攻擊。

示例場景

經典的 IDOR 攻擊發生在伺服器僅檢查使用者是否已透過身份驗證,但未檢查他們是否有權訪問物件引用時。在典型流程中,攻擊者會

  1. 以普通使用者身份登入。
  2. 找到一個引用使用者或資源 ID(例如,1234)的 URL、表單欄位或檔案。
  3. 將 ID 修改為另一個值(例如,1233)。
  4. 獲得對另一個使用者資料的未授權訪問。

在接下來的部分中,我們將探討此攻擊的一些具體示例。

URL 篡改

一種常見的 IDOR 攻擊型別涉及對 URL 中的直接物件引用進行操作。“1234” 在以下 URL 中是伺服器資料庫中使用者記錄的識別符號。如果攻擊者將此數字更改為任何其他數字(例如“1235”),並獲得了對另一個使用者資訊的訪問許可權,則您的應用程式就容易受到不安全直接物件引用攻擊。

http
# The attacker is logged in as user 1234
https://example.org/user/id/1234

# The attacker changes the id in the URL and gains access to a different user
https://example.org/user/id/1235

例如,在下面的 Express 程式碼中,URL 中提供的值可作為 req.params.id 獲取,我們使用該值從資料庫中檢索相應的記錄。我們還透過(呼叫 isAuthenticated 函式)來檢查請求是否來自已驗證的使用者。但關鍵是,我們沒有檢查已驗證使用者的 ID 是否與 URL 中的 ID 匹配,這使得一個已驗證的使用者(攻擊者)能夠獲取另一個已驗證使用者的頁面(受害者)。

js
app.get("/user/id/:id", (req, res) => {
  const user = db.users.find(req.params.id);
  if (req.isAuthenticated()) {
    // Authentication is not enough!
    res.render("user", { user });
  }
});

相反,您應該實施規則來授權訪問使用者資訊。例如,只有當登入使用者的 ID 與請求使用者的 ID 匹配時,才渲染使用者頁面。否則,返回 HTTP 401 Unauthorized 響應。

js
app.get("/user/id/:id", (req, res) => {
  const user = db.users.find(req.params.id);
  if (req.isAuthenticated() && req.session.userId === req.params.id) {
    res.render("user", { user });
  } else {
    return res.status(401).json({ message: "Unauthorized" });
  }
});

文件操縱

與 URL 篡改類似,頁面正文可以透過攻擊者修改表單元素的值來操縱,例如單選按鈕、複選框或瀏覽器開發者工具中的(隱藏)<input> 元素。例如,您的應用程式可能不在 URL 中提供使用者 ID,而是透過隱藏的表單元素傳遞使用者 ID。

html
<form action="updateUser" method="POST">
  <input type="hidden" name="user_id" value="1234" />
  <button type="submit">Update profile</button>
</form>

如果沒有執行伺服器端訪問控制,攻擊者就可以將隱藏的 <input> 元素中的 user_id 值修改為另一個使用者 ID,並可能在未經授權的情況下修改個人資料。

檔案訪問

IDOR 攻擊的一個特殊情況是訪問未受訪問控制保護的檔案或目錄。例如,如果您提供一個用於上傳 PDF 檔案的資料夾,並且上傳的檔案按順序命名,那麼如果未提供訪問控制,攻擊者就可以猜測檔名並下載所有檔案。潛在地,還可以獲取其他目錄(如伺服器配置檔案)中的檔案,這可能導致其他漏洞。

http
https://example.org/static/pdfs/1.pdf
https://example.org/static/pdfs/2.pdf

防範 IDOR 的措施

每個物件的訪問控制

防範 IDOR 攻擊最重要的措施是為使用者嘗試訪問的每個物件實施伺服器端訪問控制檢查。始終驗證已驗證的使用者是否有權訪問目標物件或對其執行操作。

識別符號的複雜性

確保資源識別符號無法被攻擊者猜測。不要在 URL 中暴露任何個人身份資訊 (PII),如使用者名稱或電子郵件地址。相反,使用唯一的、不可猜測的令牌來表示使用者。您可以使用更復雜的 ID 作為主鍵,例如 UUID,使其更難猜測有效值。然而,這隻會降低猜中有效 ID 的可能性,並不能取代適當的訪問控制。

防禦總結清單

  • 始終驗證已驗證使用者是否有權訪問或修改物件。
  • 避免暴露可預測、順序或敏感的物件識別符號(如使用者 ID 或電子郵件地址)。
  • 使用更復雜、更難預測的 ID(例如,UUID)。

另見