審計防護缺口:未受防護的對等點就是漏洞
大多數存取控制和缺失驗證的漏洞並非罕見——它們只是同一系列中,某個處理程序忘了執行其兄弟函數所執行的檢查。
admin_delete 檢查了角色,而 bulk_delete 卻沒有。
read_bounded 驗證了長度,而 read_fast 卻直接信任它。
從頭到尾逐行閱讀檔案會掩蓋這些問題;比較對等點則能將它們浮現出來。這是最具高產出的白箱技巧之一。
你在尋找的不對稱性
防護 → 接收器 (預期的安全路徑)
??? → 接收器 (缺少防護的對等路徑——就是漏洞)
何時使用
- 一個接收器可從多個呼叫點到達,且你懷疑其中一個漏掉了某項檢查。
- 你在審計一個授權模型、一組解析器家族或一群處理程序,尋找被遺忘的檢查。
- 某個發現需要將其「為何錯誤」的原因,具體呈現為與正確對等點之間的差異。
範圍檢查
僅限授權來源。如果你無法說出授權為何,請停止。
循環步驟
-
選擇一個有防護的錨點。 找到一個在敏感接收器前確實執行驗證的函數——例如授權/擁有權檢查、邊界檢查、白名單、清理器。這是你的「正確做法」參考點。
-
將防護與其保護的接收器綁定。 明確指出具體的檢查和具體的接收器。「正確」意味著防護支配了接收器:在通過錨點的每一條路徑上,檢查都在接收器之前執行。僅僅存在於函數中並非支配。
-
列舉結構上的對等點。 不要只侷限於同一檔案中的鄰近函數——重點是結構上的親緣關係:能到達相同接收器的函數;相同介面/虛擬方法的覆寫;相同路由表/分發映射/命令切換中的處理程序;類別的平行成員(
get_x/set_x/delete_x);共享輔助函數的呼叫者,其中有些清理了參數,有些則直接傳入原始值。能到達相同接收器的對等點是最強的訊號。 -
根據防護所強制的內容(而非其名稱)來比對每個對等點與錨點。 針對每個對等點,詢問是否有等效的檢查支配著相同的接收器。將缺口分類:
- absent(缺失) - 完全沒有等效檢查。
- bypassable(可繞過) - 存在但可透過某些路徑跳過(提前返回、短路
||、跳過檢查的分支)。 - weaker-than-peer(弱於對等點) - 不同類型的檢查:錨點做授權,它只做身分驗證;錨點做邊界檢查,它只做型別檢查;錨點檢查了欄位,它只檢查了其中一個欄位。
- after-sink(在接收器之後) - 檢查會執行,但在危險操作之後。
- wrong-context(錯誤上下文) - 一個實際的檢查,但不涵蓋此接收器的負載類別(例如,對於該接收器所使用的語言而言,編碼器是錯誤的)。
-
確認攻擊者輸入的可達性。 一個未受防護的接收器只有在不受信任的輸入能到達它時才算漏洞。追溯對等點中危險參數的來源至真實輸入點(交給
adjudicating-taint-paths)。總是使用常數呼叫的對等點不算發現。 -
以差異形式記錄——遵循綱要。 表述為:「錨點 A 以檢查 C(支配性)防護接收器 S;對等點 B 到達 S,其
guard_status= <absent / bypassable / weaker-than-peer / after-sink / wrong-context>,且 B 的參數經由 <來源> 受到攻擊者控制。」依照發現綱要輸出。
實際範例
錨點:
delete_own_post(user, post_id)- 在db.delete(post)之前檢查post.owner == user.id(支配性)。 對等點:admin_bulk_delete(ids)到達相同的db.delete接收器;唯一的關卡是路由層級的@login_required,沒有按物件的擁有權檢查。 差異:guard_status = weaker-than-peer- 存在身分驗證,但缺少授權(擁有權)。 可達性:ids直接來自請求主體;任何已驗證的使用者都能觸發。確認 IDOR/BFLA,嚴重性高——「任何登入使用者均可透過 id 刪除任何使用者的文章。」
應拒絕的合理化說詞
- 「函數中有檢查,所以它是有防護的。」 → 只有當它支配接收器時才算。在接收器跳過的分支上的檢查,不算防護。
- 「兩個函數都有身份驗證,它們是等價的。」 → 身份驗證不等於授權;型別檢查不等於邊界檢查。比較所強制的內容。
- 「對等點看起來沒有防護——回報它。」 → 在確認攻擊者輸入能到達接收器之前,先不要回報。無法到達 ≠ 發現。
- 「只看同一檔案中的鄰近函數。」 → 危險的對等點通常位於另一個模組中,但到達相同的接收器。依結構而非檔案來列舉。
實際執行方式
你需要能夠根據函數所到達的接收器來分組,並顯示每個函數的具體主體,以便你能逐個比較防護並檢查支配性的工具。程式屬性圖能直接回答「哪些對等點到達此接收器,以及哪些先進行驗證」;否則,就從共享接收器或輔助函數的呼叫點手動列舉對等點,並逐一閱讀。可達性步驟會重複使用 adjudicating-taint-paths。
相關技能
adjudicating-taint-paths- 確認對等點的接收器可透過輸入到達。hunting-bugs-with-a-code-graph- 此技能所依循的主循環。- FINDING-SCHEMA.md - 每個發現所需遵循的格式。