WEB安全实战--XSS 攻击的解决方案(一)
首先,项目中需要引入 xssProtect-0.1.jar、antlr-3.0.1.jar、antlr-runtime-3.0.1.jar 等3个 jar 包。
然后,封装 request,代码如下。
public class NewXssHttpServletRequestWrapper extends HttpServletRequestWrapper { HttpServletRequest orgRequest = null; public NewXssHttpServletRequestWrapper(HttpServletRequest request) { super(request); orgRequest = request; } /** * 覆盖getParameter方法,将参数名和参数值都做xss过滤。<br/> * 如果需要获得原始的值,则通过super.getParameterValues(name)来获取<br/> * getParameterNames,getParameterValues和getParameterMap也可能需要覆盖 */ @Override public String getParameter(String name) { System.out.println("NewXssFilter处理前的 Value = " + super.getParameterValues(name)); String value = super.getParameter(xssEncode(name)); if (value != null) { value = xssEncode(value); } System.out.println("NewXssFilter处理后的 Value = " + value); return value; } /** * 覆盖getHeader方法,将参数名和参数值都做xss过滤。<br/> * 如果需要获得原始的值,则通过super.getHeaders(name)来获取<br/> getHeaderNames 也可能需要覆盖 */ @Override public String getHeader(String name) { String value = super.getHeader(xssEncode(name)); if (value != null) { value = xssEncode(value); } return value; } /** * 将容易引起xss漏洞的半角字符直接替换成全角字符 * * @param s * @return */ private static String xssEncode(String s) { if (s == null || s.isEmpty()) { return s; } StringReader reader = new StringReader( s ); StringWriter writer = new StringWriter(); try { HTMLParser.process( reader, writer, new XSSFilter(), true ); return writer.toString(); } catch (NullPointerException e) { return s; } catch(Exception ex) { ex.printStackTrace(); } return null; } /** * 获取最原始的request * * @return */ public HttpServletRequest getOrgRequest() { return orgRequest; } /** * 获取最原始的request的静态方法 * * @return */ public static HttpServletRequest getOrgRequest(HttpServletRequest req) { if (req instanceof NewXssHttpServletRequestWrapper) { return ((NewXssHttpServletRequestWrapper) req).getOrgRequest(); } return req; } }
创建过滤器 NewXssFilter
public class NewXssFilter implements Filter { FilterConfig filterConfig = null; @Override public void destroy() { this.filterConfig = null; } @Override public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain) throws IOException, ServletException { String path = ((HttpServletRequest) request).getContextPath(); String basePath = request.getScheme() + "://" + request.getServerName() + ":" + request.getServerPort() + path + "/"; // HTTP 头设置 Referer过滤 String referer = ((HttpServletRequest) request).getHeader("Referer"); // REFRESH if (referer != null && referer.indexOf(basePath) < 0) { ((HttpServletRequest) request).getRequestDispatcher( ((HttpServletRequest) request).getRequestURI()).forward( ((HttpServletRequest) request), response); System.out.println("referer不为空,referer >>>>>>>>>>>>>> " + referer); } NewXssHttpServletRequestWrapper xssRequest = new NewXssHttpServletRequestWrapper((HttpServletRequest) request); chain.doFilter(xssRequest, response); } @Override public void init(FilterConfig filterConfig) throws ServletException { this.filterConfig = filterConfig; } }
在 web.xml 中配置过滤器
<filter> <filter-name>XssSqlFilter</filter-name> <filter-class>com.***.web.common.NewXssFilter</filter-class> </filter> <filter-mapping> <filter-name>XssSqlFilter</filter-name> <url-pattern>/*</url-pattern> <dispatcher>REQUEST</dispatcher> </filter-mapping>