struts2處理http請(qǐng)求參數(shù)的流程

以struts2 s2-21為例,分析跟蹤請(qǐng)求從tomcat容器到struts2框架的代碼處理流程。


tomcat部分:

tomcat 調(diào)用JIoEndpoint.java 的run()創(chuàng)建socket

然后調(diào)用processor.process(socket)負(fù)責(zé)解析http 協(xié)議并返回結(jié)果內(nèi)容。

其中processor 是HttpProcessor 的一個(gè)實(shí)例,事實(shí)上tomcat 對(duì)HTTP 請(qǐng)求的解析都是通過(guò)

HttpProcessor 這個(gè)類(lèi)中的process()這個(gè)方法實(shí)現(xiàn)的。跟入process()這個(gè)函數(shù),主要功能有以下幾個(gè):

parseRequestLine()和parseHeaders()分別解析消息頭第一行、請(qǐng)求頭其他字段等。

prepareRequest()

通過(guò)prepareRequest 方法組裝request filter,用于處理http 消息體

adapter.service(request, response)

將request 交給tomcat 處理,返回response

inputBuffer.endRequest()

將response 返回給客戶(hù)端

其中,adapter.service(request, response)將請(qǐng)求交給容器處理。tomcat從connector 到servlet 處理HTTP 請(qǐng)求。http 請(qǐng)求會(huì)依次進(jìn)入engine、host、wrapper,一直到servlet,這里開(kāi)始關(guān)聯(lián)struts2。

其中filter是struts2的FilterDispatcher實(shí)例。執(zhí)行這個(gè)doFilter 方法才開(kāi)始進(jìn)入struts2 的代碼邏輯,在

這之后程序的控制權(quán)由容器轉(zhuǎn)交給struts2。

struts2處理http請(qǐng)求

其實(shí)Struts2 的核心就是一個(gè)Filter,它的作用只是處理HTTP 請(qǐng)求(request)然后返回給客戶(hù)端(response),其doFilter方法是struts2 處理HTTP 請(qǐng)求的入口。后面struts2 將HTTP 請(qǐng)求經(jīng)過(guò)一系列處理之后,交給了參數(shù)攔截器(ParametersInterceptor),用來(lái)設(shè)置參數(shù)屬性。當(dāng)提交a=b參數(shù)時(shí),struts2會(huì)自動(dòng)執(zhí)行對(duì)應(yīng)的set a方法去設(shè)置屬性值,具體實(shí)現(xiàn)依靠OGNL完成。

參數(shù)攔截器(ParametersInterceptor)中的doIntercept 方法:

首先參數(shù)攔截器會(huì)獲取action 實(shí)例

Object action = invocation.getAction();

然后生成OGNL 上下文

ActionContext ac = invocation.getInvocationContext();

這里的ac 便是OGNL 上下文了。包括_root、_memberAccess等屬性。

通過(guò)retriveParamerers,即參數(shù)攔截器,獲取http請(qǐng)求參數(shù)。

調(diào)用ActionContext.getParameters() 實(shí)現(xiàn),獲得Map 型的參數(shù)集parameters。遍歷HttpServletRequest、HttpSession、ServletContext 中的數(shù)據(jù),并將其復(fù)制到Webwork 的Map 中實(shí)現(xiàn),至此之后,所有數(shù)據(jù)操作均在此Map 結(jié)構(gòu)中進(jìn)行,從而將內(nèi)部結(jié)構(gòu)與Servlet API 相分離。

這里newStack 是從OGNL 上下文中取出的ValueStack,保存的是action 的實(shí)例。

這里 newStack.setParameter(name, value); 便是將HTTP 請(qǐng)求的參數(shù)設(shè)置到action 實(shí)例當(dāng)中。此過(guò)程中會(huì)調(diào)用set 方法設(shè)置屬性。這里newStack.setParameter(name, value); 的執(zhí)行邏輯都是通過(guò)OGNL 實(shí)現(xiàn)的,實(shí)際上就是遍歷上下文去找對(duì)應(yīng)的set 方法。這也是為何利用ognl實(shí)現(xiàn)漏洞的原因。

在ParametersInterceptor.java的參數(shù)攔截器函數(shù)doIntercept()中,其中newStack.setParameter(name, value);函數(shù)中,判斷參數(shù)是否符合要求。

這個(gè) this. excludeParams 便是 struts2-core.jar 中 struts-default.xml 中配置的正則了。因此在s2-021漏洞中可以繞過(guò)官方修復(fù)。

s2-021 poc:Class['ClassLoader'].resources.dirContext.docBase=xxxx

因?yàn)槊總€(gè)action 必然繼承容器的 classLoader ,所以每個(gè)action 中肯定有對(duì)應(yīng) classLoader 中的屬性。這里請(qǐng)求參數(shù)是 Class['ClassLoader'].resources.dirContext.docBase ,跟蹤代碼最終找到

調(diào)用的是tomcat 源碼中BaseDirContext 類(lèi)中的 setDocBase() 方法.

?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時(shí)請(qǐng)結(jié)合常識(shí)與多方信息審慎甄別。
平臺(tái)聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點(diǎn),簡(jiǎn)書(shū)系信息發(fā)布平臺(tái),僅提供信息存儲(chǔ)服務(wù)。

相關(guān)閱讀更多精彩內(nèi)容

友情鏈接更多精彩內(nèi)容