Java安全基礎(chǔ)之Servlet核心技術(shù)
因?yàn)樵趯?shí)習(xí)中,文章更新速度可能有點(diǎn)慢,初學(xué)JAVA安全,內(nèi)容如有不恰當(dāng)?shù)牡胤?,歡迎各位大佬指正。
今天寫一下Servlet的一些核心技術(shù),后面更新完Filter之后我會對這兩個(gè)進(jìn)行一個(gè)總結(jié)。
了解Servlet知識對后續(xù)的框架審計(jì)有一定的幫助。代碼審計(jì)中我們可以選擇Servlet入手,也可以選擇從漏洞點(diǎn)反推出Http請求的入口地址。
一、Servlet的配置
不同的版本的Servlet配置不同,Servlet3.0之前的版本都是在web.xml中配置的,而Servlet3.0之后的版本則使用更為便捷的注解方式來配置。此外,不同版本的Servlet所需的Java/JDK版本也不相同。
1.1、Servlet的配置-基于web.xml
<servlet>—— 聲明servlet配置入口
<description>—— 聲明servlet描述信息
<display-name>——— 定義WEB
<servlet-name>—— 聲明Servlet名稱以便在后面的映射時(shí)使用
<servlet-class>—— 指定當(dāng)前servlet對應(yīng)的類的路徑
<servlet-mapping>—— 注冊組件訪問配置的路徑入口
<servlet-name>—— 指定上文配置的Servlet的名稱
<url-pattern>—— 指定配置這個(gè)組件的訪問路徑
二、Servlet的訪問流程
我們以如下的配置文件舉例:
首先在瀏覽器地址欄中輸入user,即訪問url-pattern標(biāo)簽中的值,然后瀏覽器發(fā)起請求,服務(wù)器通過servlet-mapping標(biāo)簽中找到文件名為user的url-pattern,通過其對應(yīng)的servlet-name尋找servlet標(biāo)簽中servlet-name相同的servlet,再通過servlet標(biāo)簽中servlet-name,獲取servlet-class參數(shù),最終得到具體的class文件路徑,繼而執(zhí)行servlet-class標(biāo)簽中class文件的邏輯。
從上述過程中可以看出,servlet和servlet-mapping中都含有<servlet-name></servlet-name>標(biāo)簽,其主要原因是通過servlet-name作為紐帶,將servlet-class和url-pattern構(gòu)成聯(lián)系,從而使url映射到servlet-class所指定的類中執(zhí)行相應(yīng)邏輯。
首先在瀏覽器地址欄中輸入user,即訪問url-pattern標(biāo)簽中的值,然后瀏覽器發(fā)起請求,服務(wù)器通過servlet-mapping標(biāo)簽中找到文件名為user的url-pattern,通過其對應(yīng)的servlet-name尋找servlet標(biāo)簽中servlet-name相同的servlet,再通過servlet標(biāo)簽中servlet-name,獲取servlet-class參數(shù),最終得到具體的class文件路徑,繼而執(zhí)行servlet-class標(biāo)簽中class文件的邏輯。
從上述過程中可以看出,servlet和servlet-mapping中都含有<servlet-name></servlet-name>標(biāo)簽,其主要原因是通過servlet-name作為紐帶,將servlet-class和url-pattern構(gòu)成聯(lián)系,從而使url映射到servlet-class所指定的類中執(zhí)行相應(yīng)邏輯。
三、Servlet的接口方法
HTTP有8中請求方式,分別為,GET、POST、HEAD、OPTIONS、PUT、DELETE、TRACE以及CONNECT方法.與此類似,Servlet接口中也對于著響應(yīng)的請求接口:GET、POST、HEAD、PUT、DELETE、OPTIONS以及TRACE,這些接口對應(yīng)著請求類型,service()方法會檢查HTTP請求類型,然后在適當(dāng)?shù)臅r(shí)候調(diào)用doGet、doPost、doPost、doPut、doDelete等方法。
3.1、Servlet的接口方法 - init()接口
在Servlet實(shí)例化后,Servlet容器會巧用init()方法來初始化該對象,主要是為例使Servlet對象在處理客戶請求錢可以完成一些初始化工作,例如建立數(shù)據(jù)庫的連接,獲取配置信息等。init()方法在第一次創(chuàng)建servlet時(shí)被調(diào)用,在后續(xù)每次用戶請求時(shí)不在被調(diào)用。
在init()方法中有一個(gè)ServletConfig參數(shù),ServletConfig代表的是配置信息,即在web.xml中配置的信息。
3.2、Servlet的接口方法 - service()接口
service()方法是執(zhí)行實(shí)際任務(wù)的主要方法,Servlet容器(即web服務(wù)器)調(diào)用service()方法來處理來自客戶端(瀏覽器)的請求,并將格式化的響應(yīng)寫回給客戶端,每次服務(wù)器接收到一個(gè)servlet請求時(shí),服務(wù)器會產(chǎn)生一個(gè)新的線程并調(diào)用服務(wù)。要注意的是,在service()方法被Servlet容器調(diào)用之前,必須確保init()方法正確完成。
一般來說service方法是不需要重寫的,因?yàn)樵贖ttpServlet中已經(jīng)有了很好的實(shí)現(xiàn),它會根據(jù)請求的方法名(GET,POST),調(diào)用doGet,doPos以及其他的doXXX方法,也就是說service是用來轉(zhuǎn)向的,所以我們一般寫一個(gè)servlet,只需要重寫doGet或者doPost就可以了。
3.3、Servlet的接口方法 - doGet() && doPost()接口
doGet()等方法根據(jù)HTTP的不同請求調(diào)用不同的方法,如果HTTP得到一個(gè)來自URL的GET請求,就會調(diào)用doGet()方法;如果得到的是一個(gè)POST請求,就會調(diào)用doPost()方法。
在servlet中默認(rèn)情況下,無論你是get還是post提交過來都會經(jīng)過service()方法來處理,然后轉(zhuǎn)向到doGet或者是doPost方法。
下面是自動生成的doGet()和doPost方法。
3.4、Servlet的接口方法 - 其他接口
destory()接口
當(dāng)Servlet容器檢測到一個(gè)Servlet對象應(yīng)該從服務(wù)中被移除時(shí),就會調(diào)用該對象的destroy()方法,以便Servlet對象釋放它所使用的資源,保存數(shù)據(jù)到持久存儲設(shè)備中,例如將內(nèi)存中的數(shù)據(jù)保存到數(shù)據(jù)庫中、關(guān)閉數(shù)據(jù)庫連接、停止后臺線程、把Cookie列表或點(diǎn)擊計(jì)數(shù)器寫到磁盤,并執(zhí)行其他類似的清理活動。destory()方法與init()方法相同,只會被調(diào)用一次。
getServeltConfig()接口
getServletConfig()方法返回Servlet容器調(diào)用init()方法時(shí)傳遞給Servlet對象的ServletConfig對象,ServletConfig對象包含Servlet的初始化參數(shù)。開發(fā)者可以在Servlet的配置文件web.xml中,使用<init-param>標(biāo)簽為servlet配置一些初始化參數(shù)。
getServletInfo()接口
getServletInfo()方法會返回一個(gè)String類型的字符串,包括關(guān)于Servlet的信息,如作者、版本及版權(quán)等。
四、Servlet的生命周期
我們常說的Servlet生命周期指的是servlet從創(chuàng)建直到銷毀的整個(gè)過程,在一個(gè)生命周期中,Servlet經(jīng)歷了被加載、初始化、接收請求、響應(yīng)請求以及提供服務(wù)的過程。
當(dāng)用戶第一次向服務(wù)器發(fā)起請求時(shí),服務(wù)器會解析用戶的請求,此時(shí)容器會加載Servlet,然后創(chuàng)建Servlet實(shí)例,再初始化servlet調(diào)用init()方法,緊接著調(diào)用服務(wù)的service()方法去處理用戶GET、POST或者其他類型的請求。當(dāng)執(zhí)行完Servlet中對應(yīng)class文件的邏輯后,將結(jié)果返回給服務(wù)器,服務(wù)器再響應(yīng)用戶請求,當(dāng)服務(wù)器不再需要Servlet實(shí)例或重新載入servlet實(shí)例或重新載入servlet時(shí)會調(diào)用destory()方法,借助該方法,Servlet可以釋放掉所以在init()方法中申請的資源。
五、總結(jié)
從本質(zhì)上來說JSP就是一個(gè)Servlet,因?yàn)镴SP文件最終會被編譯成class文件,而這個(gè)Class文件實(shí)際上就是一個(gè)特殊的Servlet
Spring MVC框架是基于Servlet技術(shù)實(shí)現(xiàn)的。
代碼審計(jì)中我們可以選擇Servlet入手,也可以選擇從漏洞點(diǎn)反推出Http請求的入口地址。
了解Servlet知識對后續(xù)的框架審計(jì)有一定的幫助。