天天看點

XWork ParameterInterceptor類繞過安全限制漏洞-解決1

這個問題是如何發生的呢?下面深入看看:

? Struts2官方站點提供的Struts 2 的整體結構

<a href="http://img1.51cto.com/attachment/201007/19/253727_1279528561kMG8.png"></a>

一個請求在Struts2架構中的處理大概分為以下幾個步驟:

Struts2架構的調用流程:

1、當Servlet容器接收到一個請求後,将請求交給你在web.xml中配置的過濾器FilterDispatcher,調用它的doFilter()方法。

2、FilterDispatcher詢問ActionMapper,以便确定這個請求是否有對應的action調用。

3、ActionMapper傳回一個描述了action調用的ActionMapping對象。

4、FilterDispatcher調用Dispatcher類的serviceAction()方法。

5、Dispatcher調用ActionProxy的executed()方法。

6、ActionProxy設定ActionInvocation對象的執行上下文,然後調用其invoke()方法。

7、ActionInvocation的invoke()方法從攔截器映射中查找尚未執行的攔截器,調用它的intercept(invocation)方法,并将自身對象的引用作為參數傳遞給攔截器。

8、攔截器完成某些預處理工作後,反過來調用ActionInvocation的invoke()方法。

ActionInvocation維護着自己的狀态,是以它知道哪些攔截器已經被執行,如果還有未執行的攔截器,就繼續執行它的intercept(invocation)方法。

9、如果所有的攔截器都已經執行過了,就調用action執行個體的executed()方法(如果struts.xml檔案中沒有被設定成其他方法的話)。

10、ActionInvocation根據action執行傳回的接過碼,查找對應的Result,調用Result的executed(invocation)的方法,将結果頁面呈現給使用者。

11、ActionInvocation的invoke()方法将控制權傳回給攔截器映射中的最後一個攔截器,該攔截器完成所有必須的後期處理工作,然後從interce(invocation)方法傳回,允許前一個攔截器執行它自己的後續處理工作。如次反複,直到所有的攔截器都成功傳回。

12、ActionInvocation的invoke()方法執行完畢後,向ActionProxy傳回一個String類型的結果碼,最後,ActionProxy清理狀态并傳回。

這個究竟發生在哪個流程呢?

我們通路:

<a href="http://test.struts.com/admin/modelAdmin!listModel.action?cid=000H000A">http://test.struts.com/admin/modelAdmin!listModel.action?cid=000H000A</a>

DEBUG整個流程:

DEBUG [com.opensymphony.xwork2.interceptor.StaticParametersInterceptor] - Setting static parameters {}

2010-07-19 13:36:26,718

DEBUG [com.opensymphony.xwork2.interceptor.ParametersInterceptor] - Setting params cid =&amp;gt; [ 000H000A ]

可以看到,發生在攔截器那個流程,處理請求參數的ParameterInterceptor 類,還記得第七步說什麼嗎?

就是調用:ParameterInterceptor 的

intercept(ActionInvocation invocation)

public class ParametersInterceptor extends MethodFilterInterceptor

{

public String doIntercept(ActionInvocation invocation)

    throws Exception

  {

    Object action = invocation.getAction();

    if (!(action instanceof NoParameters)) {

      ActionContext ac = invocation.getInvocationContext();

      Map parameters = ac.getParameters();

      if (LOG.isDebugEnabled()) {

LOG.debug("Setting params " + getParameterLogMap(parameters));

      }

      if (parameters != null) {

        Map contextMap = ac.getContextMap();

        try {

          OgnlContextState.setCreatingNullObjects(contextMap, true);

          OgnlContextState.setDenyMethodExecution(contextMap, true);

          OgnlContextState.setReportingConversionErrors(contextMap, true);

          ValueStack stack = ac.getValueStack();

          setParameters(action, stack, parameters);

        } finally {

          OgnlContextState.setCreatingNullObjects(contextMap, false);

          OgnlContextState.setDenyMethodExecution(contextMap, false);

          OgnlContextState.setReportingConversionErrors(contextMap, false);

        }

    }

    return invocation.invoke();

  }

,,,,

本文轉自jooben 51CTO部落格,原文連結:http://blog.51cto.com/jooben/352955