1. 程式人生 > >Struts網站基於Filter的XSS漏洞修復

Struts網站基於Filter的XSS漏洞修復

1,關於XSS漏洞的知識,網上有很多文件,例如點選開啟連結

2,關於XSS漏洞修復的知識也有很多,本文對本人修復XSS做下記錄

3,Spring 中 XSS漏洞修復的可以參考 點選開啟連結

4,但是以上方法僅僅適用於Spring 的修復,Struct有自己的攔截包裝機制,完整的 Struct 中 Xss 漏洞修復,可以參考 點選開啟連結

5,但是以上對Struct中Xss漏洞修復的程式碼有點多,我們知道對於一個已經維護多年的web專案而言,修復一個問題最好用盡可能少的程式碼完成,於是本人結合以上兩篇文章給出修復方案

6,利用javax.servlet.Filter 和 org.apache.struts2.dispatcher.StrutsRequestWrapper 實現最小程式碼量攔截Xss攻擊

7,Filer程式碼如下

public class XSSFilter implements Filter {

    private static final Logger LOGGER = LoggerFactory.getLogger(XSSFilter.class);

    @Override
    public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain) throws IOException,
            ServletException {
        HttpServletRequest httpRequest = (HttpServletRequest) request;
        String currentURI = httpRequest.getRequestURI();
        String targetURI = currentURI.substring(currentURI.indexOf("/", 1));
        LOGGER.info("targetURI:{}", targetURI);
        chain.doFilter(new XSSStrutsRequestWrapper((HttpServletRequest) request), response);  
    }
    @Override
    public void init(FilterConfig filterConfig) throws ServletException {
    }
    @Override
    public void destroy() {
    }
}
8,Wrapper程式碼如下
public class XSSStrutsRequestWrapper extends StrutsRequestWrapper {
    private static final Logger LOG = LoggerFactory.getLogger(XSSStrutsRequestWrapper.class);
	public XSSStrutsRequestWrapper(HttpServletRequest req) {
		super(req);
	}

	@Override
    public String getParameter(String name) {
    	name = StringEscapeUtils.escapeHtml4(name);
        // 返回值之前 先進行過濾
        return StringEscapeUtils.escapeHtml4(super.getParameter(name));
    }

    @Override
    public String[] getParameterValues(String name) {
    	name = StringEscapeUtils.escapeHtml4(name);
        // 返回值之前 先進行過濾
        String[] values = super.getParameterValues(name);
        if(values != null){
            for (int i = 0; i < values.length; i++) {
                values[i] = StringEscapeUtils.escapeHtml4(values[i]);
            }
        }
        return values;
    }

	@Override
	public Enumeration<String> getParameterNames() {
		Enumeration<String> names = super.getParameterNames();
		while(names.hasMoreElements()){
			String name = names.nextElement();
			name = StringEscapeUtils.escapeHtml4(name);
		}
		return names;
	}
	
	@Override
    public Map getParameterMap() {
	    LOG.info("getParameterMap");
        Map paramMap = super.getParameterMap();
        if (CollectionUtils.isEmpty(paramMap)) {
            return paramMap;
        }
        for (Object value : paramMap.values()) { 
            String[] str = (String[])value;
            if (str != null) {
                for (int i = 0; i < str.length; i++) {
                    str[i] = StringEscapeUtils.escapeHtml4(str[i]);
                }
            }
        }
        LOG.info("ParameterMap" + JSON.toJSONString(paramMap));
        return paramMap;
    }
}

9,web.xml中攔截器配置
	 <filter>
        <filter-name>strutsXSSFilter</filter-name>
        <filter-class>com.my.web.xss.XSSFilter</filter-class>
    </filter>
     <filter-mapping>
        <filter-name>strutsXSSFilter</filter-name>
        <url-pattern>*.action</url-pattern>
    </filter-mapping>

10,以上對於filter的配置中要注意,url-pattern的匹配規則只有三種:

精確匹配:如:/mytest.action,只會匹配mytest.action這個url

路徑匹配:如:/my/*,會匹配my為字首的url

字尾匹配:如:*.action,會匹配.action為字尾url

11,以上僅對非multipart/form-data請求做攔截,涉及multipart/form-data的請求還需要在Filter中做請求校驗,

然後再寫一個org.apache.struts2.dispatcher.multipart.MultiPartRequestWrapper的類