[英]How to fix the HTTP Response splitting vulnerability with ESAPI
在最近的 findbugs (FB) 運行后,它抱怨一個:安全 - HTTP 響應拆分漏洞以下代碼觸發它:
String referrer = req.getParameter("referrer");
if (referrer != null) {
launchURL += "&referrer="+(referrer);
}
resp.sendRedirect(launchURL);
基本上,'referrer' http 參數包含一個 url,當單擊我們應用程序中的后退按鈕時,瀏覽器將返回到該 url。 它作為參數附加到 url。 經過一番研究,我知道我需要清理引薦來源網址。 經過更多研究,我發現esapi項目似乎提供了這種功能:
//1st canonicalize
import org.owasp.esapi.Encoder;
import org.owasp.esapi.Validator;
import org.owasp.esapi.reference.DefaultEncoder;
import org.owasp.esapi.reference.DefaultValidator;
[...]
Encoder encoder = new DefaultEncoder(new ArrayList<String>());
String cReferrer = encoder.canonicalize(referrer);
但是我不知道如何檢測例如 jscript 代碼或其他不屬於引薦來源網址的內容。 那么我怎樣才能用 esapi 實現呢?
我試過了:
Validator validator = new DefaultValidator(encoder);
validator.isValidInput("Redirect URL",referrer,"HTTPParameterValue",512,false);
但是這不起作用。 我需要的是一個函數,它導致:
http://www.google.com/login?dest=http://google.com/%0D%0ALocation : javascript:%0D%0A%0D%0Aalert(document.cookie) (不行)
或者調用以下語句就足夠了?
encoder.encodeForHTMLAttribute(referrer);
任何幫助表示贊賞。
如果有人感興趣,這是我的最終解決方案。 首先我規范化然后 URL 解碼字符串。 如果 CR 或 LF 存在 (\\n \\r),我只是剪切了以 \\n 或 \\r 開頭的潛在“攻擊”字符串的其余部分。
String sanitize(String url) throws EncodingException{
Encoder encoder = new DefaultEncoder(new ArrayList<String>());
//first canonicalize
String clean = encoder.canonicalize(url).trim();
//then url decode
clean = encoder.decodeFromURL(clean);
//detect and remove any existent \r\n == %0D%0A == CRLF to prevent HTTP Response Splitting
int idxR = clean.indexOf('\r');
int idxN = clean.indexOf('\n');
if(idxN >= 0 || idxR>=0){
if(idxN<idxR){
//just cut off the part after the LF
clean = clean.substring(0,idxN);
}
else{
//just cut off the part after the CR
clean = clean.substring(0,idxR);
}
}
//re-encode again
return encoder.encodeForURL(clean);
}
從理論上講,我可以稍后針對 ESAPI.properties 中定義的“HTTPParameterValue”正則表達式驗證該值,但是它不喜歡 http:// 中的冒號,我沒有進一步調查。
測試后還有一句話:現在大多數現代瀏覽器(Firefox> 3.6,Chrome,IE10等)都檢測到這種漏洞並且不執行代碼......
我建議使用白名單方法,其中您只檢查referrer
字符串中允許的字符。 正則表達式將是一個不錯的選擇。
編輯:
您使用的類org.owasp.esapi.reference.DefaultEncoder
並沒有真正編碼任何東西。 看看方法的源代碼encodeForHTMLAttribute(referrer)
在這里grepcode 。 典型的 URL 編碼(編碼回車和換行) 也無濟於事。
因此,前進的道路將是設備一些驗證邏輯,用於檢查有效的字符集。 這是另一篇有見地的文章。
我認為您的想法是正確的,但使用的是不合適的編碼器。 Referer [sic] 標頭值實際上是一個 URL,而不是 HTML 屬性,因此您確實要使用:
encoder.encodeForURL(referrer);
-凱文
如果字符串中有“\\n\\r”,則接受的答案將不起作用。 示例:如果我有字符串: "This is str\\n\\rstr"
,它返回"This is str\\nstr"
上述接受答案的修正版本是:
String sanitizeCarriageReturns(String value) {
int idxR = value.indexOf('\r');
int idxN = value.indexOf('\n');
if (idxN >= 0 || idxR >= 0) {
if ((idxN > idxR && idxR<0) || (idxR > idxN && idxR>=0)) {
value = value.substring(0, idxN);
} else if (idxN < idxR){
value = value.substring(0, idxR);
}
}
return value;
}
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.