/* * Copyright (c) 2008-2016 Computer Network Information Center (CNIC), Chinese Academy of Sciences. * * This file is part of Duckling project. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. * */ package cn.vlabs.umt.ui.servlet.filters; /** * @author Tom */ import java.io.IOException; import java.net.URI; import java.net.URISyntaxException; import javax.servlet.Filter; 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; import javax.servlet.http.HttpServletRequestWrapper; import net.duckling.cloudy.common.CommonUtils; import org.apache.log4j.Logger; public class XssFilter implements Filter { private static final Logger LOGGER = Logger .getLogger(XssHttpServletRequestWrapper.class); private class XssHttpServletRequestWrapper extends HttpServletRequestWrapper { public XssHttpServletRequestWrapper(HttpServletRequest request) { super(request); } /** * 将容易引起xss漏洞的半角字符直接替换成全角字符 * * @param s * @return */ private String xssEncode(String s) { if (s == null || s.equals("")) { return s; } for (int i = 0; i < filterChars.length; i++) { if (s.contains(filterChars[i])) { s = s.replace(filterChars[i], replaceChars[i]); } } return s; } /** * 覆盖getHeader方法,将参数名和参数值都做xss过滤。<br/> * 如果需要获得原始的值,则通过super.getHeaders(name)来获取<br/> * getHeaderNames 也可能需要覆盖 */ public String getHeader(String name) { String value = super.getHeader(xssEncode(name)); if (value != null) { value = xssEncode(value); } return value; } /** * 覆盖getParameter方法,将参数名和参数值都做xss过滤。<br/> * 如果需要获得原始的值,则通过super.getParameterValues(name)来获取<br/> * getParameterNames,getParameterValues和getParameterMap也可能需要覆盖 */ public String getParameter(String name) { if (isNeverParameter(name)) { return super.getParameter(name); } if (isIgnoreparameter(name)) { String param = super.getParameter(name); if (param == null) { return null; } try { URI uri=new URI(param); return CommonUtils.trim(param); } catch (URISyntaxException e) { return null; } } String value = super.getParameter(xssEncode(name)); if (value != null) { value = xssEncode(value); } return CommonUtils.trim(value); } private boolean isNeverParameter(String name) { if (name == null) { return false; } for (String ignoreInput : neverInputs) { if (name.equals(ignoreInput)) { return true; } } return false; } private boolean isIgnoreparameter(String name) { if (name == null) { return false; } for (String ignoreInput : ignoreInputs) { if (name.equals(ignoreInput)) { return true; } } return false; } public String[] getParameterValues(String name) { if (isNeverParameter(name)) { return super.getParameterValues(name); } if (isIgnoreparameter(name)) { String[] param = super.getParameterValues(name); if (param == null) { return null; } int index = 0; for (String pa : param) { try{ URI uri=new URI(pa); param[index++]=pa; }catch(URISyntaxException e){ param[index++] = ""; } } return param; } String[] parameters = super.getParameterValues(name); if (parameters == null || parameters.length == 0) { return null; } for (int i = 0; i < parameters.length; i++) { parameters[i] = xssEncode(parameters[i]); } return parameters; } public String getQueryString() { String value = super.getQueryString(); if (value != null) { value = xssEncode(value); } return value; } } private String[] filterChars; private String[] replaceChars; private String[] ignoreInputs = new String[] {}; private String[] neverInputs = new String[] {}; public void destroy() { // Do nothing } public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain) throws IOException, ServletException { XssHttpServletRequestWrapper xssRequest = new XssHttpServletRequestWrapper( (HttpServletRequest) request); chain.doFilter(xssRequest, response); } public void init(FilterConfig filterConfig) throws ServletException { String filterChar = filterConfig.getInitParameter("FilterChar"); String replaceChar = filterConfig.getInitParameter("ReplaceChar"); String splitChar = filterConfig.getInitParameter("SplitChar"); String ignoreChar = filterConfig.getInitParameter("IgnoreInput"); String xssConf = filterConfig.getInitParameter("XssConf"); String neverChar = filterConfig.getInitParameter("NeverInput"); if (filterChar != null && filterChar.length() > 0) { filterChars = filterChar.split(splitChar); } if (replaceChar != null && replaceChar.length() > 0) { replaceChars = replaceChar.split(splitChar); } if (ignoreChar != null && !ignoreChar.isEmpty()) { ignoreInputs = ignoreChar.split(splitChar); } if (neverChar != null && !neverChar.isEmpty()) { neverInputs = neverChar.split(splitChar); } } }