繼續對Fortify的漏洞進行總結,本篇主要針對 Open Redirect(開放式重定向) 的漏洞進行總結,如下:
1.1、產生原因:
通過重定向,Web 應用程序能夠引導用戶訪問同一應用程序內的不同網頁或訪問外部站點。應用程序利用重定向來幫助進行站點導航,有時還跟蹤用戶退出站點的方式。當 Web 應用程序將客戶端重定向到攻擊者可以控制的任意 URL 時,就會發生 Open redirect 漏洞。
攻擊者可以利用 Open redirect 漏洞誘騙用戶訪問某個可信賴站點的 URL,並將他們重定向到惡意站點。攻擊者通過對 URL 進行編碼,使最終用戶很難注意到重定向的惡意目標,即使將這一目標作為 URL 參數傳遞給可信賴的站點時也會發生這種情況。因此,Open redirect 常被作為釣魚手段的一種而濫用,攻擊者通過這種方式來獲取最終用戶的敏感數據。
例 1:以下 JSP 代碼會在用戶打開鏈接時,指示用戶瀏覽器打開從 dest 請求參數中解析的 URL。
<%
...
String strDest = request.getParameter("dest");
pageContext.forward(strDest);
...
%>
如果受害者收到一封電子郵件,指示該用戶打開 "http://trusted.example.com/ecommerce/redirect.asp?dest=www.wilyhacker.com" 鏈接,用戶有可能會打開該鏈接,因為他會認為這個鏈接將轉到可信賴的站點。然而,一旦用戶打開該鏈接,上面的代碼會將瀏覽器重定向至 "http://www.wilyhacker.com"。 很多用戶都被告知,要始終監視通過電子郵件收到的 URL,以確保鏈接指向一個他們所熟知的可信賴站點。盡管如此,如果攻擊者對目標 URL 進行 16 進制編碼:
"http://trusted.example.com/ecommerce/redirect.asp?dest=%77%69%6C%79%68%61%63%6B%65%72%2E%63%6F%6D",那么,即使再聰明的最終用戶也可能會被欺騙,打開該鏈接。
1.2、修復方案:
Fortify提供方案:
不應當允許未驗證的用戶輸入控制重定向機制中的目標 URL。而應采用間接方法:創建一份合法 URL 列表,用戶可以指定其中的內容並且只能從中進行選擇。利用這種方法,就絕不會直接使用用戶提供的輸入來指定要重定向到的 URL。
例 2:以下代碼引用了一個通過有效 URL 傳播的數組。用戶單擊的鏈接將通過與所需 URL 對應的數組索引來傳遞。
<%
...
try {
int strDest = Integer.parseInt(request.getParameter("dest"));
if((strDest >= 0) && (strDest <= strURLArray.length -1 )) {
strFinalURL = strURLArray[strDest];
pageContext.forward(strFinalURL);
}
}catch (NumberFormatException nfe) {
// Handle exception
...
}
...
%>
但在某些情況下,這種方法並不可行,因為這樣一份合法 URL 列表過於龐大、難以跟蹤。這種情況下,有一種類似的方法也能限制用於重定向用戶的域,這種方法(黑名單)至少可以防止攻擊者向用戶發送惡意的外部站點。
實際解決方案:
圖1.2.1:使用重定向的方式跳轉頁面
將原有的sendRedirect()跳轉方法替換成setStatus()方法進行跳轉。
圖1.2.2:調用setStatus()方法返回自定義狀態碼
在js 文件中對setStatus()方法返回的狀態碼進行對應頁面的跳轉。
圖1.2.3:根據setStatus()方法返回的狀態碼跳轉到指定頁面