Search code examples
javaparametersfilterstruts

How to get raw parameters before mapping


I've got new issue with Struts 1 framework. I need to filter some input values from page, so I wrote my custom filter to do this.

It works great for single parameters, that are not mapped to any form. But it doesn't get parameters when it have been mapped to some struts Form field.

Does anyone have idea how to deal with it?

Here is code of my Filter

public class XSSFillter implements Filter {


@Override
public void doFilter(ServletRequest request, ServletResponse response,
        FilterChain chain) throws IOException, ServletException {
    chain.doFilter(new XSSRequest((HttpServletRequest) request), response);
}

@Override
public void init(FilterConfig filterConfig) throws ServletException {       
}

@Override
public void destroy() {
}
    }

And

public class XSSRequest extends MultipartRequestWrapper{

public XSSRequest(HttpServletRequest request) {
    super(request);
}

@Override
public String[] getParameterValues(String name) {
    String[] values = super.getParameterValues(name);

    if(values == null){
        return null;
    }

    String[] newValues = new String[values.length];

    for(int index = 0; index < values.length; index++ ){
        newValues[index] = XSSFilterUtil.removeXSSTokens(values[index]);
    }

    return newValues;
}

@Override
public String getParameter(String name) {
    String value = super.getParameter(name); 
    return XSSFilterUtil.removeXSSTokens(value);
}

@Override
public String getHeader(String name) {
    String value = super.getHeader(name);
    return XSSFilterUtil.removeXSSTokens(value);
}
}

Of course I've defined it in web.xml

Here is one of most important part, I guess.

if (isMultipart) {
            parameterValue = multipartParameters.get(name);
        } else {
            parameterValue = request.getParameterValues(name);
        }

So in one case parameterValue is taken from multipartParameters, and in turn they are defined in some temporary files. I thinks the best way will be modified all request parameters and then let it go throw Struts 1.3.8 library.


Solution

  • After two days of researching and experementations I found some solution. I wrote custom MultipartRequestHandler

    public class XSSMultipartRequestHandler extends CommonsMultipartRequestHandler {
    
        @Override
        public Hashtable getAllElements() {
            Hashtable table = super.getAllElements();
            for (Object key : table.keySet()) {
                Object value = table.get(key);
                if (value instanceof String[]) {
                    String[] arr = (String[]) value;
                    String[] newValue = { XSSFilterUtil.removeXSSTokens(arr[0]) };
                    table.put(key, newValue);
                }
            }
            return table;
        }
    
    }
    

    Also u need to write custom RequestProcessor, because before validation struts wrap request to MultipartRequestWrapper

    public class XSSRequestProcessor extends TilesRequestProcessor {
    
        @Override
        protected boolean processValidate(HttpServletRequest request,
                HttpServletResponse response, ActionForm form, ActionMapping mapping)
                throws IOException, ServletException, InvalidCancelException {
            return super.processValidate(new XSSFilteredRequest(request), response, form, mapping);
        }
    
    }
    

    and in struts-config

    <controller processorClass="com.package.filter.XSSRequestProcessor" multipartClass="com.package.filter.XSSMultipartRequestHandler" contentType="text/html; charset=UTF-8"/>
    

    That's all :)