Fortify漏洞之 Log Forging(日誌偽造)
繼續對Fortify的漏洞進行總結,本篇主要針對 Log Forging(日誌偽造)的漏洞進行總結,如下:
1.1、產生原因:
在以下情況下會發生 Log Forging 的漏洞:
1. 數據從一個不可信賴的數據源進入應用程序。
2. 數據寫入到應用程序或系統日誌文件中。
為了便於以後的審閱、統計數據收集或調試,應用程序通常使用日誌文件來儲存事件或事務的歷史記錄。根據應用程序自身的特性,審閱日誌文件可在必要時手動執行,也可以自動執行,即利用工具自動挑選日誌中的重要事件或帶有某種傾向性的信息。
如果攻擊者可以向隨後會被逐字記錄到日誌文件的應用程序提供數據,則可能會妨礙或誤導日誌文件的解讀
例 1: 下列 Web 應用程序代碼會嘗試從一個請求對象中讀取整數值。如果數值未被解析為整數,輸入就會被記錄到日誌中,附帶一條提示相關情況的錯誤消息。
...
String val = request.getParameter("val");
try {
int value = Integer.parseInt(val);
}catch (NumberFormatException nfe) {
log.info("Failed to parse val = " + val);
}
...
如果用戶為“val”提交字符串“twenty-one”,則日誌中會記錄以下條目:
INFO: Failed to parse val=twenty-one
然而,如果攻擊者提交字符串 “twenty-one%0a%0aINFO:+User+logged+out%3dbadguy”,則日誌中會記錄以下條目:
INFO: Failed to parse val=twenty-one
INFO: User logged out=badguy
顯然,攻擊者可以使用同樣的機制插入任意日誌條目。
1.2、修復方案:
使用間接方法防止 Log Forging 攻擊:創建一組與不同事件一一對應的合法日誌條目,這些條目必須記錄在日誌中,並且僅記錄該組條目。要捕獲動態內容(如用戶註銷系統),請務必使用由服務器控制的數值,而非由用戶提供的數據。這就確保了日誌條目中絕不會直接使用由用戶提供的輸入。
可以按以下方式將例 1 重寫為與 NumberFormatException 對應的預定義日誌條目:
...
public static final String NFE = "Failed to parse val. The input is required to be an integer value."
...
String val = request.getParameter("val");
try {
int value = Integer.parseInt(val);
}catch (NumberFormatException nfe) {
log.info(NFE);
}
..
在某些情況下,這個方法有些不切實際,因為這樣一組合法的日誌條目實在太大或是太復雜了。這種情況下,開發者往往又會退而采用黑名單方法。在輸入之前,黑名單會有選擇地拒絕或避免潛在的危險字符。然而,不安全字符列表很快就會不完善或過時。更好的方法是創建一份白名單,允許其中的字符出現在日誌條目中,並且只接受完全由這些經認可的字符組成的輸入。在大多數 Log Forging 攻擊中,最關鍵的字符是“\n”(換行符),該字符決不能出現在日誌條目白名單中。
圖1.2.1:過濾引起Log Forging漏洞的敏感字符的公共方法
Fortify漏洞之 Log Forging(日誌偽造)