只需要配置一个拦截器即可解决参数内容替换
一、配置web.xml
<filter><filter-name>struts-xssFilter</filter-name><filter-class>*.*.filters.XssFilter</filter-class></filter><filter-mapping><filter-name>struts-xssFilter</filter-name><url-pattern>/*</url-pattern></filter-mapping>
二、编写XssFilter
import javax.servlet.*;
import javax.servlet.http.HttpServletRequest;
import java.io.IOException;
public class XssFilter implements Filter{FilterConfig filterConfig = null;/*** Default constructor.*/public XssFilter() {}public void destroy() {this.filterConfig = null;}public void init(FilterConfig fConfig) throws ServletException {this.filterConfig = fConfig;}public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain) throws IOException, ServletException {HttpServletRequest req = (HttpServletRequest) request;String url = req.getRequestURI();//过滤不需要拦截的actionif(url.indexOf("*.action") != -1){chain.doFilter(request, response);}else{chain.doFilter(new XssHttpServletRequestWrapper((HttpServletRequest) request), response);}}
}
三、XssHttpServletRequestWrapper 实现 StrutsRequestWrapper完成参数替换
import cn.hutool.http.HtmlUtil;
import org.apache.commons.lang.StringUtils;
import org.apache.struts2.dispatcher.StrutsRequestWrapper;
import org.springframework.util.CollectionUtils;import javax.servlet.http.HttpServletRequest;
import java.util.Enumeration;
import java.util.Map;
import java.util.regex.Pattern;
public class XssHttpServletRequestWrapper extends StrutsRequestWrapper {HttpServletRequest orgRequest = null;public XssHttpServletRequestWrapper(HttpServletRequest servletRequest) {super(servletRequest);orgRequest = servletRequest;}/*** 重写getParameterValues方法* 通过循环取出每一个请求结果* 再对请求结果进行过滤* */public String[] getParameterValues(String parameter) {String[] values = super.getParameterValues(parameter);if (values == null) {return null;}int count = values.length;String[] encodedValues = new String[count];for (int i = 0; i < count; i++) {encodedValues[i] = cleanXSS(values[i]);}return encodedValues;}/*** 重写getParameter方法* 对请求结果进行过滤* */public String getParameter(String parameter) {String value = super.getParameter(parameter);if (value == null) {return null;}return cleanXSS(value);}public String getHeader(String name) {String value = super.getHeader(name);if (value == null)return null;return cleanXSS(value);}/*** 获取最原始的request** @return*/public HttpServletRequest getOrgRequest() {return orgRequest;}/*** 获取最原始的request的静态方法** @return*/public static HttpServletRequest getOrgRequest(HttpServletRequest req) {if (req instanceof XssHttpServletRequestWrapper) {return ((XssHttpServletRequestWrapper) req).getOrgRequest();}return req;}@Overridepublic Enumeration<String> getParameterNames() {Enumeration<String> names = super.getParameterNames();while(names.hasMoreElements()){String name = names.nextElement();name = cleanXSS(name);}return names;}@Overridepublic Map 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] = cleanXSS(str[i]);}}}return paramMap;}private String cleanXSS(String value) {if (StringUtils.isNotBlank(value)) {// 推荐使用ESAPI库来避免脚本攻击,value = HtmlUtil.filter(value);// 避免空字符串value = value.replaceAll(" ", "");// 避免script 标签Pattern scriptPattern = Pattern.compile("<script>(.*?)</script>", Pattern.CASE_INSENSITIVE);value = scriptPattern.matcher(value).replaceAll("");// 避免src形式的表达式scriptPattern = Pattern.compile("src[\r\n]*=[\r\n]*\\\'(.*?)\\\'",Pattern.CASE_INSENSITIVE | Pattern.MULTILINE | Pattern.DOTALL);value = scriptPattern.matcher(value).replaceAll("");scriptPattern = Pattern.compile("src[\r\n]*=[\r\n]*\\\"(.*?)\\\"",Pattern.CASE_INSENSITIVE | Pattern.MULTILINE | Pattern.DOTALL);value = scriptPattern.matcher(value).replaceAll("");// 删除单个的 </script> 标签scriptPattern = Pattern.compile("</script>", Pattern.CASE_INSENSITIVE);value = scriptPattern.matcher(value).replaceAll("");// 删除单个的<script ...> 标签scriptPattern = Pattern.compile("<script(.*?)>",Pattern.CASE_INSENSITIVE | Pattern.MULTILINE | Pattern.DOTALL);value = scriptPattern.matcher(value).replaceAll("");// 避免 eval(...) 形式表达式scriptPattern = Pattern.compile("eval\\((.*?)\\)",Pattern.CASE_INSENSITIVE | Pattern.MULTILINE | Pattern.DOTALL);value = scriptPattern.matcher(value).replaceAll("");// 避免 expression(...) 表达式scriptPattern = Pattern.compile("expression\\((.*?)\\)",Pattern.CASE_INSENSITIVE | Pattern.MULTILINE | Pattern.DOTALL);value = scriptPattern.matcher(value).replaceAll("");// 避免 javascript: 表达式scriptPattern = Pattern.compile("javascript:", Pattern.CASE_INSENSITIVE);value = scriptPattern.matcher(value).replaceAll("");// 避免 vbscript:表达式scriptPattern = Pattern.compile("vbscript:", Pattern.CASE_INSENSITIVE);value = scriptPattern.matcher(value).replaceAll("");// 避免 onload= 表达式scriptPattern = Pattern.compile("onload(.*?)=",Pattern.CASE_INSENSITIVE | Pattern.MULTILINE | Pattern.DOTALL);value = scriptPattern.matcher(value).replaceAll("");}return value;}
四、pom需要引入hutool
<dependency><groupId>cn.hutool</groupId><artifactId>hutool-all</artifactId><version>5.6.0</version></dependency>
五、测试结果通过