漏洞與補丁齊飛,藍屏共死機一色。
最近struts2的安全漏洞影響面甚廣,此后門為可以在url中直接遠程調用腳本的漏洞和一個重定向漏洞。大家可以在s2-016遠程執行腳本漏洞和s2-017重定向開放漏洞中看到攻擊的例子。第一個漏洞即遠程執行腳本通過構造ProcessBuilder創建進程執行腳本,框架開放度太大,由外界用戶輸入的字符串可以被當成代碼執行。第二個漏洞重定向開放則可被釣魚網站利用,外鏈上偽造成如著名電子商務網站淘寶,京東,比如是<a href="http://www.taobao.com/xxx.action?redirect:http://hacker.com/getyourPassword">打折新款</a>, 用戶點擊后來到一個釣魚網站,這網站可以跟淘寶或京東網站登陸界面做的一樣,來欺騙用戶進行獲取密碼。
struts2作為一個老牌的web開源框架,尚且存在如此嚴重的問題,我們作為應用程序的開發者,也經常會在某些地方由於對框架理解不深,或考慮的不夠周到,而埋下安全或其他方面的隱患。下面我們就談談經常碰到的一些高危地段:
1: String para = req.getParameter("g");
2: if (para != null) {
3: RequestDispatcher r = req.getRequestDispatcher("/goodbye/ww");
4: r.forward(req, res);
5: }
6:
7: System.out.println("still in here.Logic continue.");
這段代碼在forward之后,Response就已經發送給客戶端,看起來后面的代碼就沒執行了,其實不是的。forward之后,只是網絡交互已經完成,這時如果調用一個新的r.forward會擲出java.lang.IllegalStateException: Cannot forward after response has been committed 異常,而后續代碼照樣執行。如果此時調用了一個后台服務,如標記數據庫或其他資源操作,就會造成嚴重的邏輯錯誤。
解決方案:在forward之后不需要執行其它后台邏輯時,請及時return.(手制動)
此類問題在論壇、博客等用戶可輸入html文本的網站中碰到的比較多。用戶輸入一段文字,這段文字需要以網頁形式展現出來(作為html執行或作為js執行)或者需要生成一個后台腳本(如sql,shell等),這時用戶可惡意的輸入腳本並在其后的執行環境中執行,達到控制或破壞系統的目的。
基本解決思路:
將這段代碼腳本進行處理,比如將其中有較大風險的字符進行轉義處理,使其在執行環境中只有展示功能,而無執行功效。(限行)
- 對於html,javascript只需將其進行html轉義即可。(考慮到展示效果的問題,最好的辦法是創建標簽白名單,只有在白名單中的標簽才可以展示,否則就轉義或剔除)。
- 標簽語言中的變量生成的html,可以對其進行標簽定制,提供轉義屬性,形如
<c:out value="${html}" escapeXml="true" /> 形式。
- 對於SQL盡量使用Preparestatement來生成sql,少用拼接方式;如果要用拼接,則注意用戶輸入的內容其中字符的轉義。
Servlet本身設計時刻允許多線程訪問,提供web服務給客戶端。其中容器中Servlet中的實例變量一般來說是只有一個的(跟隨servlet只初始化一個這個特點),那如果有對此實例並發寫的情況,很容易造成寫丟失等同步問題。但是進行同步加鎖過多,又會造成性能下降等問題。在一般情況下盡量少用實例變量來維持狀態。如若要用,也盡量使用線程安全且性能高的容器,如ConcurrentHashMap,而要避免使用線程不安全的如HashMap(可能造成死循環),ArrayList,LinkedList等。




