首先说一下思路,防止这种类似于注入攻击,就是使用拦截器(Filter)处理特殊字符或过滤特殊字符
今天介绍一个方法,利用覆盖Servlet的getParameter方法达到处理特殊字符的目的来解决(防止)Xss攻击
web.xml
<filter> <filter-name>XssEscape</filter-name> <filter-class>www.ablanxue.com.filter.XssFilter</filter-class> </filter> <filter-mapping> <filter-name>XssEscape</filter-name> <url-pattern>/*</url-pattern> <dispatcher>REQUEST</dispatcher> </filter-mapping>Filter类(XssFilter. Jav a )
package www.ablanxue.com.filter; import java.io.IOException; import javax.servlet.FilterChain; import javax.servlet.FilterConfig; import javax.servlet.ServletException; import javax.servlet.ServletRequest; import javax.servlet.ServletResponse; import javax.servlet.http.HttpServletRequest; public class XssFilter implements javax.servlet.Filter { @Override public void destroy() { // TODO Auto-generated method stub } @Override public void doFilter(ServletRequest request, ServletResponse response, FilterChain filterChain) throws IOException, ServletException { XssHttpServletRequestWrapper xssRequest = new XssHttpServletRequestWrapper((HttpServletRequest) request); filterChain.doFilter(xssRequest, response); } @Override public void init(FilterConfig arg0) throws ServletException { // TODO Auto-generated method stub } }
最关键的类(XssHttpServletRequestWrapper.java)
继承servlet的HttpServletRequestWrapper,并重写相应的几个有可能带xss攻击的方法
package www.ablanxue.com.filter; import java.io.StringReader; import java.io.StringWriter; import javax.servlet.http.HttpServletRequest; import javax.servlet.http.HttpServletRequestWrapper; import com.blogspot.radialmind.html.HTMLParser; import com.blogspot.radialmind.xss.XSSFilter; public class XssHttpServletRequestWrapper extends HttpServletRequestWrapper { HttpServletRequest orgRequest = null; public XssHttpServletRequestWrapper(HttpServletRequest request) { super(request); orgRequest = request; } /** * 覆盖getParameter方法,将参数名和参数值都做xss过滤。 * 如果需要获得原始的值,则通过super.getParameterValues(name)来获取 * getParameterNames,getParameterValues和getParameterMap也可能需要覆盖 */ @Override public String getParameter(String name) { String value = super.getParameter(xssEncode(name)); if (value != null) { value = xssEncode(value); } return value; } /** * 覆盖getHeader方法,将参数名和参数值都做xss过滤。 * 如果需要获得原始的值,则通过super.getHeaders(name)来获取 * 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); String result = writer.toString(); System.out.println("xssEncode-------------------------" + s + " = " + result); return result; } 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 XssHttpServletRequestWrapper) { return ((XssHttpServletRequestWrapper) req).getOrgRequest(); } return req; } }
通过重写getParameter()等方法,实现简单的过滤,从而防止Xss攻击