使用filter解决xss攻击

使用filter解决xss攻击的实现思路,其实是通过正则的方式对请求的参数做脚本的过滤,但是这需要对所要过滤的脚本做很多的枚举。下面这个demo是我在工作中用到的,希望对大家有所帮助。

主要实现方法是重写HttpServletRequestWrapper中的getParameter,getParameterMap,以及getParameterValues等方法处理请求的参数值

其中xssEncode()方法我只是对传入的< >进行了圆角<>替换,有简单js防止脚本注入,但是这远远不够,所以在stripXss()方法中枚举了很多存在脚本注入的正则表达式,对文本进行过滤处理。重写这个类之后,你需要定义一个XSSFilter,filter中调用该重写的HttpServletRequestWrapper。具体看代码

public class XSSFilter implements Filter {

    public void destroy() {
        // TODO Auto-generated method stub

    }


    /**
     * 通过url只能访问action
     */
    public void doFilter(ServletRequest req, ServletResponse res, FilterChain chain) throws IOException,
            ServletException {
            HttpServletRequest request = (HttpServletRequest) req;
            request.setCharacterEncoding("utf-8");
            XssHttpServletRequestWrapper xssRequest = new XssHttpServletRequestWrapper(request);
            chain.doFilter(xssRequest, res);
    }

    public void init(FilterConfig arg0) throws ServletException {
        // TODO Auto-generated method stub

    }

}


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; } @Override public Map getParameterMap() { Map map = super.getParameterMap(); if (map != null) { for (Map.Entry entry : map.entrySet()) { String[] values = entry.getValue(); List newValues = new LinkedList(); if (values != null) { for (String s : values) { String afertEncode = xssEncode(s); newValues.add(afertEncode); } entry.setValue(newValues.toArray(new String[newValues.size()])); } } } return map; } @Override public String[] getParameterValues(String name) { String[] values = super.getParameterValues(name); return xssEncode(values); } protected String[] xssEncode(String[] values) { if (values != null && values.length > 0) { int length = values.length; String[] escapseValues = new String[length]; for (int i = 0; i < length; i++) { escapseValues[i] = xssEncode(values[i]); } return escapseValues; } return values; } /** * 覆盖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 || "".equals(s)) { return s; } StringBuilder sb = new StringBuilder(s.length() + 16); for (int i = 0; i < s.length(); i++) { char c = s.charAt(i); switch (c) { case '>': sb.append('>');// 全角大于号 break; case '<': sb.append('<');// 全角小于号 break; default: sb.append(c); break; } } String value = stripXss(sb.toString()); return value; } /** *过滤script脚本 * @param value * @return */ private static String stripXss(String value){ if(StringUtils.isNotEmpty(value)){ Pattern scriptPattern =Pattern.compile("", Pattern.CASE_INSENSITIVE); value=scriptPattern.matcher(value).replaceAll(""); scriptPattern = Pattern.compile("", Pattern.CASE_INSENSITIVE); value = scriptPattern.matcher(value).replaceAll(""); scriptPattern = Pattern.compile("", Pattern.CASE_INSENSITIVE | Pattern.MULTILINE | Pattern.DOTALL); value = scriptPattern.matcher(value).replaceAll(""); scriptPattern = Pattern.compile("javascript:", Pattern.CASE_INSENSITIVE); value = scriptPattern.matcher(value).replaceAll(""); scriptPattern = Pattern.compile("", Pattern.CASE_INSENSITIVE); value = scriptPattern.matcher(value).replaceAll(""); scriptPattern = Pattern.compile("", Pattern.CASE_INSENSITIVE); value = scriptPattern.matcher(value).replaceAll(""); scriptPattern = Pattern.compile("", Pattern.CASE_INSENSITIVE | Pattern.MULTILINE | Pattern.DOTALL); value = scriptPattern.matcher(value).replaceAll(""); scriptPattern = Pattern.compile("onload(.*?)=", Pattern.CASE_INSENSITIVE | Pattern.MULTILINE | Pattern.DOTALL); value = scriptPattern.matcher(value).replaceAll(""); scriptPattern = Pattern.compile("oninput(.*?)=", Pattern.CASE_INSENSITIVE | Pattern.MULTILINE | Pattern.DOTALL); value = scriptPattern.matcher(value).replaceAll(""); scriptPattern = Pattern.compile("onerror(.*?)=", Pattern.CASE_INSENSITIVE | Pattern.MULTILINE | Pattern.DOTALL); value = scriptPattern.matcher(value).replaceAll(""); scriptPattern = Pattern.compile("onclick(.*?)=", Pattern.CASE_INSENSITIVE | Pattern.MULTILINE | Pattern.DOTALL); value = scriptPattern.matcher(value).replaceAll(""); scriptPattern = Pattern.compile("confirm(.*?)", Pattern.CASE_INSENSITIVE | Pattern.MULTILINE | Pattern.DOTALL); value = scriptPattern.matcher(value).replaceAll(""); scriptPattern = Pattern.compile("onfocus(.*?)=", Pattern.CASE_INSENSITIVE | Pattern.MULTILINE | Pattern.DOTALL); value = scriptPattern.matcher(value).replaceAll(""); scriptPattern = Pattern.compile("alert(.*?)", Pattern.CASE_INSENSITIVE | Pattern.MULTILINE | Pattern.DOTALL); value = scriptPattern.matcher(value).replaceAll(""); } return value; } // public static void main(String[] args) { // System.out.println(stripXss("alert(gergerrg)")); // } /** * 获取最原始的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; } }


你可能感兴趣的:(java)