/** * Filter配置 * * @author xxx */ @Configuration public class FilterConfig { @Value("${xss.enabled}") private String enabled; @Value("${xss.excludes}") private String excludes; @Value("${xss.urlPatterns}") private String urlPatterns; @SuppressWarnings({ "rawtypes", "unchecked" }) @Bean public FilterRegistrationBean xssFilterRegistration() { FilterRegistrationBean registration = new FilterRegistrationBean(); // registration.setDispatcherTypes(DispatcherType.REQUEST); //过滤器类(继承Filter) registration.setFilter(new XssFilter()); // registration.addUrlPatterns(StringUtils.split(urlPatterns, ",")); // registration.setName("xssFilter"); // registration.setOrder(Integer.MAX_VALUE); Map<String, String> initParameters = Maps.newHashMap(); initParameters.put("excludes", excludes); initParameters.put("enabled", enabled); //Filter 初始化参数 registration.setInitParameters(initParameters); return registration; } }
/** * 防止XSS攻击的过滤器 * * @author xxx */ public class XssFilter implements Filter { /** * 排除链接 */ public List<String> excludes = new ArrayList<>(); /** * xss过滤开关 */ public boolean enabled = false; @Override public void init(FilterConfig filterConfig) throws ServletException { String tempExcludes = filterConfig.getInitParameter("excludes"); String tempEnabled = filterConfig.getInitParameter("enabled"); if (StringUtils.isNotEmpty(tempExcludes)) { String[] url = tempExcludes.split(","); for (int i = 0; url != null && i < url.length; i++) { excludes.add(url[i]); } } if (StringUtils.isNotEmpty(tempEnabled)) { enabled = Boolean.valueOf(tempEnabled); } } @Override public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain) throws IOException, ServletException { HttpServletRequest req = (HttpServletRequest) request; HttpServletResponse resp = (HttpServletResponse) response; if (handleExcludeURL(req, resp)) { chain.doFilter(request, response); return; } XssHttpServletRequestWrapper xssRequest = new XssHttpServletRequestWrapper((HttpServletRequest) request); chain.doFilter(xssRequest, response); } private boolean handleExcludeURL(HttpServletRequest request, HttpServletResponse response) { if (!enabled) { return true; } if (excludes == null || excludes.isEmpty()) { return false; } String url = request.getServletPath(); for (String pattern : excludes) { Pattern p = Pattern.compile("^" + pattern); Matcher m = p.matcher(url); if (m.find()) { return true; } } return false; } @Override public void destroy() { } }
/** * XSS过滤处理 * * @author xxx */ public class XssHttpServletRequestWrapper extends HttpServletRequestWrapper { /** * @param request */ public XssHttpServletRequestWrapper(HttpServletRequest request) { super(request); } @Override public String[] getParameterValues(String name) { String[] values = super.getParameterValues(name); if (values != null) { int length = values.length; String[] escapseValues = new String[length]; for (int i = 0; i < length; i++) { // 防xss攻击和过滤前后空格 escapseValues[i] = Jsoup.clean(values[i], Whitelist.relaxed()).trim();
//过滤LDAP攻击
escapseValues[i] = StrUtils.getLDAPFilter(escapseValues[i]);
} return escapseValues; } return super.getParameterValues(name); } }
private static final char[] LDAP_FILTER_ESCAPE_SEQUENCE = new char[]{'\', '*', '(', ')', ' ', '/'}; private static final String[] LDAP_FILTER_ESCAPE_SEQUENCE_CHARACTER = new String[]{"\5c", "\2a", "\28", "\29", "\00", "\2f"}; //防止LDAP注入参数过滤函数 public static String getLDAPFilter(String userInput) { if (StrUtils.isBlank(userInput)) { return userInput; } String tmp = userInput; for (int charIndex = 0; charIndex < LDAP_FILTER_ESCAPE_SEQUENCE.length; ++charIndex) { int index = tmp.indexOf(LDAP_FILTER_ESCAPE_SEQUENCE[charIndex]); if (index != -1) { tmp = tmp.replace(String.valueOf(LDAP_FILTER_ESCAPE_SEQUENCE[charIndex]), LDAP_FILTER_ESCAPE_SEQUENCE_CHARACTER[charIndex]); } } return tmp; }