主頁(yè) > 知識(shí)庫(kù) > JSP應(yīng)用的安全問(wèn)題

JSP應(yīng)用的安全問(wèn)題

熱門標(biāo)簽:長(zhǎng)春回?fù)芡夂粝到y(tǒng)廠家 廣州三五防封電銷卡 電銷外呼系統(tǒng) 排行榜 地圖標(biāo)注制作道路 地圖標(biāo)注創(chuàng)業(yè)項(xiàng)目入駐 四川電信外呼系統(tǒng)靠譜嗎 外呼系統(tǒng)啥意思 珠海銷售外呼系統(tǒng)運(yùn)營(yíng)商 山東智能云外呼管理系統(tǒng)
一、概述  
當(dāng)網(wǎng)絡(luò)編程越來(lái)越方便,系統(tǒng)功能越來(lái)越強(qiáng)大,安全性卻指數(shù)倍地下降。這恐怕就是網(wǎng)絡(luò)編程的不幸和悲哀了。各種動(dòng)態(tài)內(nèi)容生成環(huán)境繁榮了WWW,它們的設(shè)計(jì)目標(biāo)就是為了給開(kāi)發(fā)者更多的力量,給最終用戶更多的方便。正因?yàn)槿绱?,系統(tǒng)設(shè)計(jì)師和開(kāi)發(fā)者必須明確地把安全問(wèn)題作為一個(gè)考慮因素,事后追悔很難奏效。  
從安全的角度來(lái)看,服務(wù)器端WWW應(yīng)用的弱點(diǎn)來(lái)源于各種各樣的交互能力和傳輸通道。它們是攻擊者直接可以用來(lái)影響系統(tǒng)的工具。在攻擊者尋找和利用系統(tǒng)安全漏洞時(shí),它們總是給系統(tǒng)安全帶來(lái)壓力。對(duì)付所有這些攻擊的通用防衛(wèi)策略就是所謂的輸入驗(yàn)證。  
從同一層面考慮,主要有兩種設(shè)計(jì)上的錯(cuò)誤導(dǎo)致了安全方面的問(wèn)題:  
· 拙劣的訪問(wèn)控制,以及  
· 對(duì)部署環(huán)境作隱含的假設(shè)。  
在有關(guān)安全的文獻(xiàn)中,針對(duì)訪問(wèn)控制問(wèn)題有著許多深入的分析。這里我們要討論的是底層實(shí)現(xiàn)(代碼和配置)上的安全管理問(wèn)題,討論的環(huán)境是JSP?;蛘哒f(shuō),我們將討論惡意的用戶輸入偽裝自身以及改變應(yīng)用預(yù)定行為的各種方法,考慮如何檢驗(yàn)輸入合法性以及減少對(duì)信息和應(yīng)用接口的不受歡迎的探測(cè)。  
二、JSP概述  
JSP技術(shù)允許把Java代碼邏輯嵌入到HTML和XML文檔之內(nèi),為創(chuàng)建和管理動(dòng)態(tài)WWW內(nèi)容帶來(lái)了方便。JSP頁(yè)面由JSP引擎預(yù)先處理并轉(zhuǎn)換成Java Servlet,此后如果出現(xiàn)了對(duì)JSP頁(yè)面的請(qǐng)求,Web服務(wù)器將用相應(yīng)的Servlet輸出結(jié)果作為應(yīng)答。雖然JSP和Servlet在功能上是等價(jià)的,但是,和Servlet相比,JSP的動(dòng)態(tài)內(nèi)容生成方法恰好相反:JSP是把Java代碼嵌入到文檔之中,而不是把文檔嵌入到Java應(yīng)用之中。為訪問(wèn)外部功能和可重用的對(duì)象,JSP提供了一些用來(lái)和JavaBean組件交互的額外標(biāo)記,這些標(biāo)記的語(yǔ)法和HTML標(biāo)記相似。值得注意的是:HTML語(yǔ)法屬于JSP語(yǔ)法的一個(gè)子集(一個(gè)純HTML文檔是一個(gè)合法的JSP頁(yè)面),但反過(guò)來(lái)不一定正確。特別地,為了便于動(dòng)態(tài)生成內(nèi)容和格式,JSP允許在標(biāo)記之內(nèi)嵌入其他標(biāo)記。例如,下面是一段合法的JSP代碼:  
A HREF = "%= request.getRemoteUser() %>">  
從本文后面可以看到,這種結(jié)構(gòu)增加了安全問(wèn)題的復(fù)雜性。  
與CGI相比,JSP具有更好的性能和會(huì)話管理(即會(huì)話狀態(tài)持久化)機(jī)制。這主要通過(guò)在同一個(gè)進(jìn)程之內(nèi)運(yùn)用Java線程處理多個(gè)Servlet實(shí)現(xiàn),而CGI一般要求為每一個(gè)請(qǐng)求分別創(chuàng)建和拆除一個(gè)進(jìn)程。  
三、安全問(wèn)題  
由于完全開(kāi)放了對(duì)服務(wù)器資源的訪問(wèn),從JSP頁(yè)面轉(zhuǎn)換得到的不安全Servlet可能給服務(wù)器、服務(wù)器所在的網(wǎng)絡(luò)、訪問(wèn)頁(yè)面的客戶機(jī)之中的任意一個(gè)或全體帶來(lái)威脅,甚至通過(guò)DDoS或蠕蟲(chóng)分布式攻擊,還可能影響到整個(gè)Internet。人們往往假定,Java作為一種類型安全的、具有垃圾收集能力的、具有沙箱(Sandbox)機(jī)制的語(yǔ)言,它能夠奇跡般地保證軟件安全。而且事實(shí)上,許多在其他語(yǔ)言中存在的低層次安全問(wèn)題,比如緩沖或堆溢出,很少給Java程序帶來(lái)危害。然而,這并不意味著人們很難寫(xiě)出不安全的Java程序,特別是對(duì)編寫(xiě)Servlet來(lái)說(shuō)。驗(yàn)證輸入和控制對(duì)資源的訪問(wèn)是始終必須關(guān)注的問(wèn)題。另外,JSP的體系結(jié)構(gòu)相當(dāng)復(fù)雜,其中包含許多相互協(xié)作的子系統(tǒng)。這些子系統(tǒng)之間的交互常常是安全隱患的根源。除此之外,雖然現(xiàn)在所有的JSP實(shí)現(xiàn)都圍繞著Java,但JSP規(guī)范允許幾乎所有其他語(yǔ)言扮演這個(gè)角色。這樣,這些替代語(yǔ)言的安全問(wèn)題也必須加以考慮。  
簡(jiǎn)而言之,在JSP系統(tǒng)中產(chǎn)生安全漏洞的機(jī)會(huì)是相當(dāng)多的。下面我們將討論它們中最常見(jiàn)的一部分。  
四、非置信用戶輸入的一般問(wèn)題  
非置信的用戶輸入(Untrusted User Input)實(shí)際上包含了所有的用戶輸入。用戶輸入來(lái)源于客戶端,可以通過(guò)許多不同的途徑到達(dá)服務(wù)器端,有時(shí)甚至是偽裝的。為JSP服務(wù)器提供的用戶輸入包括(但不限于):  
· 請(qǐng)求URL的參數(shù)部分,  
· HTML表單通過(guò)POST或GET請(qǐng)求提交的數(shù)據(jù),  
· 在客戶端臨時(shí)保存的數(shù)據(jù)(也就是Cookie),  
· 數(shù)據(jù)庫(kù)查詢,  
· 其它進(jìn)程設(shè)置的環(huán)境變量。  
用戶輸入的問(wèn)題在于,它們由服務(wù)器端的應(yīng)用程序解釋,所以攻擊者可以通過(guò)修改輸入數(shù)據(jù)達(dá)到控制服務(wù)器脆弱部分的目的。服務(wù)器的脆弱部分常常表現(xiàn)為一些數(shù)據(jù)訪問(wèn)點(diǎn),這些數(shù)據(jù)由用戶提供的限定詞標(biāo)識(shí),或通過(guò)執(zhí)行外部程序得到。  
JSP能夠調(diào)用保存在庫(kù)里面的本地代碼(通過(guò)JNI)以及執(zhí)行外部命令。類Runtime提供了一個(gè)exec()方法。exec()方法把它的第一個(gè)參數(shù)視為一個(gè)需要在獨(dú)立的進(jìn)程中執(zhí)行的命令行。如果這個(gè)命令字符串的某些部分必須從用戶輸入得到,則用戶輸入必須先進(jìn)行過(guò)濾,確保系統(tǒng)所執(zhí)行的命令和它們的參數(shù)都處于意料之內(nèi)。即使命令字符串和用戶輸入沒(méi)有任何關(guān)系,執(zhí)行外部命令時(shí)仍舊必須進(jìn)行必要的檢查。在某些情況下,攻擊者可能修改服務(wù)器的環(huán)境變量影響外部命令的執(zhí)行。例如,修改path環(huán)境變量,讓它指向一個(gè)惡意的程序,而這個(gè)惡意程序偽裝成了exec()所調(diào)用程序的名字。為了避免這種危險(xiǎn),在進(jìn)行任何外部調(diào)用之前顯式地設(shè)置環(huán)境變量是一種較好的習(xí)慣。具體的設(shè)置方法是:在exec()調(diào)用中,把一個(gè)環(huán)境變量的數(shù)組作為第二個(gè)參數(shù),數(shù)組中的元素必須是name=value格式。  
當(dāng)用戶輸入用來(lái)標(biāo)識(shí)程序打開(kāi)的任意類型的輸入/輸出流時(shí),類似的問(wèn)題也會(huì)出現(xiàn)。訪問(wèn)文件、數(shù)據(jù)庫(kù)或其他網(wǎng)絡(luò)連接時(shí)不應(yīng)該依賴于未經(jīng)檢驗(yàn)的用戶輸入。另外,打開(kāi)一個(gè)流之后,把用戶輸入直接發(fā)送給它是很不安全的。對(duì)于SQL查詢來(lái)說(shuō)這一點(diǎn)尤其突出。下面訪問(wèn)JDBC API的JSP代碼片斷很不安全,因?yàn)楣粽呖梢栽谒峤坏妮斎胫星度敕指裘畹淖址?,從而達(dá)到執(zhí)行危險(xiǎn)命令的目的:  
%@ page import="java.sql.*" %> !-- 這里加上一些打開(kāi)SQL Server連接的代碼 --> % Statement stmt = connection.getStatement(); String query = "SELECT * FROM USER_RECORDS WHERE USER = " + request.getParameter("username"); ResultSet result = Statement.executeQuery(query); %>
如果username包含一個(gè)分號(hào),例如:  
http://server/db.jsp? username=joe;SELECT%20*%20FROM%20SYSTEM_RECORDS
一些版本的SQL Server會(huì)忽略整個(gè)查詢,但還有一些版本的SQL Server將執(zhí)行兩個(gè)命令。如果是后者,攻擊者就可以訪問(wèn)原本沒(méi)有資格訪問(wèn)的數(shù)據(jù)庫(kù)資源(假定Web服務(wù)器具有訪問(wèn)權(quán)限)。  
進(jìn)行適當(dāng)?shù)妮斎霗z驗(yàn)可以防止這類問(wèn)題出現(xiàn)。  
五、輸入檢驗(yàn)  
從安全的角度來(lái)看,輸入檢驗(yàn)包括對(duì)來(lái)自外部數(shù)據(jù)源(非置信數(shù)據(jù)源,參見(jiàn)前面說(shuō)明)的數(shù)據(jù)進(jìn)行語(yǔ)法檢查,有時(shí)還要進(jìn)行語(yǔ)義檢查。依賴于應(yīng)用的關(guān)鍵程度和其他因素,作為輸入檢驗(yàn)結(jié)果而采取的動(dòng)作可能是下面的一種或者多種:  
· 忽略語(yǔ)法上不安全的成分,  
· 用安全的代碼替換不安全的部分,  
· 中止使用受影響的代碼,  
· 報(bào)告錯(cuò)誤,  
· 激活一個(gè)入侵監(jiān)測(cè)系統(tǒng)。  
輸入檢驗(yàn)可以按照以下兩種模式之一進(jìn)行:列舉不安全的字符并拒絕它們;定義一組安全的字符,然后排除和拒絕不安全的字符。這兩種模式分別稱為正向和反向輸入過(guò)濾。一般地,正向輸入過(guò)濾更簡(jiǎn)單和安全一些,因?yàn)樵S多時(shí)候,要列舉出服務(wù)器端應(yīng)用、客戶端瀏覽器、Web服務(wù)器和操作系統(tǒng)可能誤解的字符并不是一件容易的事情。  
請(qǐng)參見(jiàn)本文下面“通過(guò)嵌入標(biāo)記實(shí)現(xiàn)的攻擊”部分中輸入檢驗(yàn)的例子,這個(gè)例子示范了如何避免誤解惡意提交的輸入內(nèi)容。  
六、GET請(qǐng)求和Cookie中的敏感數(shù)據(jù)  
就象CGI協(xié)議所定義的,把請(qǐng)求數(shù)據(jù)從客戶端傳輸?shù)椒?wù)器端最簡(jiǎn)單的方法是GET請(qǐng)求方法。使用GET請(qǐng)求方法時(shí),輸入數(shù)據(jù)附加到請(qǐng)求URL之后,格式如下:  
URL[?name=value[name=value[...]]]
顯然,對(duì)于傳輸敏感數(shù)據(jù)來(lái)說(shuō),這種編碼方式是不合適的,因?yàn)橥ǔG闆r下,整個(gè)URL和請(qǐng)求字符串都以明文方式通過(guò)通信通道。所有路由設(shè)備都可以和服務(wù)器一樣記錄這些信息。如果要在客戶請(qǐng)求中傳輸敏感數(shù)據(jù),我們應(yīng)該使用POST方法,再加上一種合適的加密機(jī)制(例如,通過(guò)SSL連接)。從JSP引擎的角度來(lái)看,在很大程度上,使用哪種傳輸方法無(wú)關(guān)緊要,因?yàn)閮烧叩奶幚矸绞揭粯印?nbsp; 
在WWW的發(fā)展過(guò)程中,Netscape引入了Cookie的概念。Cookie是服務(wù)器保存到客戶端的少量信息,服務(wù)器提取這些信息以維持會(huì)話狀態(tài)或跟蹤客戶端瀏覽器的活動(dòng)。JSP提供了一個(gè)response隱含對(duì)象的addCookie()方法,用來(lái)在客戶端設(shè)置Cookie;提供了一個(gè)request()對(duì)象的getCookie()方法,用來(lái)提取Cookie的內(nèi)容。Cookie是javax.servlet.http.Cookie類的實(shí)例。由于兩個(gè)原因,如果把敏感數(shù)據(jù)保存到Cookie,安全受到了威脅:第一,Cookie的全部?jī)?nèi)容對(duì)客戶端來(lái)說(shuō)都是可見(jiàn)的;第二,雖然瀏覽器一般不提供偽造Cookie的能力,但沒(méi)有任何東西能夠阻止用戶用完全偽造的Cookie應(yīng)答服務(wù)器。  
一般而言,任何客戶端瀏覽器提交的信息都不可以假定為絕對(duì)安全。  
七、通過(guò)嵌入標(biāo)記實(shí)現(xiàn)的攻擊  
CERT Advisory CA-2000-02描述了客戶在請(qǐng)求中嵌入惡意HTML標(biāo)記的問(wèn)題。這個(gè)問(wèn)題一般被稱為“cross site scripting”問(wèn)題,但它的名字有些用詞不當(dāng),因?yàn)樗粌H僅和腳本有關(guān),同時(shí),它和“跨越網(wǎng)站”(cross site)也沒(méi)有什么特別的關(guān)系。不過(guò),這個(gè)名字出現(xiàn)時(shí),問(wèn)題還沒(méi)有被人們廣泛了解。  
這種攻擊通常包含一個(gè)由用戶提交的病態(tài)腳本,或者包含惡意的HTML(或XML)標(biāo)記,JSP引擎會(huì)把這些內(nèi)容引入到動(dòng)態(tài)生成的頁(yè)面。這種攻擊可能針對(duì)其他用戶進(jìn)行,也可能針對(duì)服務(wù)器,但后者不太常見(jiàn)。“cross site scripting”攻擊的典型例子可以在論壇服務(wù)器上看到,因?yàn)檫@些服務(wù)器允許用戶在自己提交的文章中嵌入格式化標(biāo)記。通常,被濫用的標(biāo)記是那些能夠把代碼嵌入到頁(yè)面的標(biāo)記,比如SCRIPT>、OBJECT>、APPLET>和EMBED>。另外還有一些標(biāo)記也會(huì)帶來(lái)危險(xiǎn),特別地,F(xiàn)ORM>可能被用于欺騙瀏覽者暴露敏感信息。下面是一個(gè)包含惡意標(biāo)記的請(qǐng)求字符串的例子:  
http://server/jsp_script.jsp?poster=evilhacker& message=SCRIPT>evil_code/SCRIPT>
要防止出現(xiàn)這種問(wèn)題當(dāng)然要靠輸入檢查和輸出過(guò)濾。這類檢查必須在服務(wù)器端進(jìn)行,不應(yīng)依賴于客戶端腳本(比如JavaScript),因?yàn)闆](méi)有任何東西能夠阻止用戶逃避客戶端檢驗(yàn)過(guò)程。  
下面的代碼片斷示范了如何在服務(wù)器端檢查嵌入的標(biāo)記:  
!-- HTML代碼結(jié)束 -->% 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 ('+','_'); %>p>你提交的消息是:hr/>tt>%= message %>/tt>hr/>/p>!-- 下面加上其他HTML代碼 -->
由于要列舉出所有不合法的字符比較困難,所以更安全的方法是進(jìn)行正向過(guò)濾,即除了那些確實(shí)允許出現(xiàn)的字符之外(例如[A-Za-z0-9]),丟棄(或者轉(zhuǎn)換)所有其他字符。  
八、關(guān)于JavaBean的說(shuō)明  
JSP按照J(rèn)avaBean規(guī)范描述的一系列約定,在JSP頁(yè)面中快速、方便地訪問(wèn)可重用的組件(Java對(duì)象)。每個(gè)JavaBean組件封裝了一些可以不依賴于調(diào)用環(huán)境而獨(dú)立使用的數(shù)據(jù)和功能。Bean包含數(shù)據(jù)成員(屬性),并通過(guò)Get和Set方法實(shí)現(xiàn)訪問(wèn)這些屬性的標(biāo)準(zhǔn)API。  
為快速初始化指定Bean的所有屬性,JSP提供了一種快捷方式,即在查詢字符串中提供name=value對(duì),并讓它匹配目標(biāo)屬性的名字。考慮下面這個(gè)使用Bean的例子(以XML格式顯示):  
jsp:useBean id="myBasket" class="BasketBean"> jsp:setProperty name="myBasket" property="*"/> jsp:useBean> html> head>title>你的購(gòu)物籃/title>/head> body> p> 你已經(jīng)把商品: jsp::getProperty name="myBasket" property="newItem"/> 加入到購(gòu)物籃 br/> 金額是$ jsp::getProperty name="myBasket" property="balance"/> 準(zhǔn)備 a href="checkout.jsp">付款/a>
注意在setProperty方法調(diào)用中使用的通配符號(hào)“*”。這個(gè)符號(hào)指示JSP設(shè)置查詢字符串中指定的所有屬性的值。按照本意,這個(gè)腳本的調(diào)用方式如下:  
http://server/addToBasket.jsp?newItem=ITEM0105342
正常情況下,HTML表單構(gòu)造的查詢字符串就是這種形式。但問(wèn)題在于,沒(méi)有任何東西能夠防止用戶設(shè)置balance屬性:  
http://server/addToBasket.jsp? newItem=ITEM0105342balance=0
處理頁(yè)面的jsp:setProperty>標(biāo)記時(shí),JSP容器會(huì)把這個(gè)參數(shù)映射到Bean中具有同樣名字的balance屬性,并嘗試把該屬性設(shè)置為0。  
為避免出現(xiàn)這種問(wèn)題,JSP開(kāi)發(fā)者必須在Bean的Set和Get方法中實(shí)現(xiàn)某種安全措施(Bean必須對(duì)屬性進(jìn)行強(qiáng)制的訪問(wèn)控制),同時(shí),在使用jsp:setProperty>的通配符時(shí)也應(yīng)該小心謹(jǐn)慎。  
九、實(shí)現(xiàn)上的漏洞與源代碼安全  
無(wú)論是哪一種JSP實(shí)現(xiàn),在一定的階段,它們的某些版本都會(huì)出現(xiàn)給系統(tǒng)帶來(lái)危險(xiǎn)的安全隱患,即使JSP開(kāi)發(fā)者遵從了安全編程慣例也無(wú)濟(jì)于事。例如,在Allaire的JRun的一個(gè)版本中,如果請(qǐng)求URL包含字符串“.jsp%00”作為JSP腳本擴(kuò)展名的一部分,服務(wù)器不會(huì)忽略null字節(jié),它會(huì)把頁(yè)面視為一個(gè)靜態(tài)的非JSP頁(yè)面之類的東西。這樣,服務(wù)器會(huì)請(qǐng)求操作系統(tǒng)打開(kāi)該頁(yè)面,而這時(shí)null字節(jié)卻被忽略,結(jié)果提供給用戶的是JSP頁(yè)面的源代碼而不是頁(yè)面的執(zhí)行結(jié)果。  
類似地,Tomcat的一個(gè)版本也有一個(gè)安全隱患。只要請(qǐng)求類如下面的格式,它會(huì)讓攻擊者看到JSP頁(yè)面的源代碼:  
http://server/page.js%2570
這里的騙局在于,%25是URL編碼的“%”,而70是“p”的十六進(jìn)制值。Web服務(wù)器不會(huì)調(diào)用JSP處理器(因?yàn)閁RL沒(méi)有以“.jsp”結(jié)尾),但靜態(tài)文件處理器會(huì)設(shè)法把URL映射到正確的文件名字(再一次解碼URL)。  
另外,許多Web服務(wù)器和JSP實(shí)現(xiàn)都帶有示范腳本,這些示范腳本常常包含安全隱患。在把服務(wù)器部署到一個(gè)不無(wú)惡意的環(huán)境(即Internet)之前,禁止對(duì)所有這些腳本的訪問(wèn)有利于安全。  
簡(jiǎn)而言之,JSP開(kāi)發(fā)者應(yīng)該清楚:在自己正在開(kāi)發(fā)的平臺(tái)上,當(dāng)前有哪些安全隱患。訂閱BUGTRAQ和所有供應(yīng)商提供的郵件列表是跟蹤這類信息的好方法。  
結(jié)束語(yǔ)  
JSP和任何其他強(qiáng)大的技術(shù)一樣。如果要保證被部署系統(tǒng)的安全和可靠,應(yīng)用JSP時(shí)必須小心謹(jǐn)慎。在這篇文章中,我們簡(jiǎn)要地討論了JSP腳本中常常出現(xiàn)的代碼和配置級(jí)安全問(wèn)題,提出了降低由此帶來(lái)的安全風(fēng)險(xiǎn)的建議。  
您可能感興趣的文章:
  • 編寫(xiě)線程安全的JSP程序
  • JSP安全性初探
  • Java線程安全中的單例模式
  • java編譯時(shí)出現(xiàn)使用了未經(jīng)檢查或不安全的操作解決方法
  • 深入理解:Java是類型安全的語(yǔ)言,而C++是非類型安全的語(yǔ)言
  • Java語(yǔ)言的接口與類型安全
  • JSP學(xué)習(xí)之Java Web中的安全控制實(shí)例詳解

標(biāo)簽:吳忠 廣元 保定 玉樹(shù) 肇慶 紹興 北海 潮州

巨人網(wǎng)絡(luò)通訊聲明:本文標(biāo)題《JSP應(yīng)用的安全問(wèn)題》,本文關(guān)鍵詞  JSP,應(yīng),用的,安全,問(wèn)題,JSP,;如發(fā)現(xiàn)本文內(nèi)容存在版權(quán)問(wèn)題,煩請(qǐng)?zhí)峁┫嚓P(guān)信息告之我們,我們將及時(shí)溝通與處理。本站內(nèi)容系統(tǒng)采集于網(wǎng)絡(luò),涉及言論、版權(quán)與本站無(wú)關(guān)。
  • 相關(guān)文章
  • 下面列出與本文章《JSP應(yīng)用的安全問(wèn)題》相關(guān)的同類信息!
  • 本頁(yè)收集關(guān)于JSP應(yīng)用的安全問(wèn)題的相關(guān)信息資訊供網(wǎng)民參考!
  • 推薦文章