# xssFilter **Repository Path**: l502387174/xss-filter ## Basic Information - **Project Name**: xssFilter - **Description**: xss过滤器 - **Primary Language**: Java - **License**: Not specified - **Default Branch**: master - **Homepage**: None - **GVP Project**: No ## Statistics - **Stars**: 8 - **Forks**: 5 - **Created**: 2021-03-18 - **Last Updated**: 2023-06-09 ## Categories & Tags **Categories**: Uncategorized **Tags**: 学习 ## README @[toc] # xssFilter # 背景 框架中添加xss攻击过滤器类,防止脚本攻击,能够做到引入包即可使用。 # 参考资料 这里主要参考[renren-fast](https://www.renren.io/guide)官方提供的开源项目的xss攻击进行改造。 > 参考io/renren/common/xss包下面类 三方包 [hutool-http](https://mvnrepository.com/artifact/cn.hutool/hutool-http/5.6.0),[参考博客api](https://www.cnblogs.com/SceneryHao/articles/10969100.html)里面提供了xss所需的标签替换等功能 # 上代码 ## 过滤器配置 ``` /** * Filter配置 * * @author lirui */ @Configuration public class FilterConfig { /** * 注册过滤器 * * @param url 提供可不拦截接口 * 实现配置不过滤部分接口,部分接口需要不做过滤 * @return */ @Bean public FilterRegistrationBean xssFilterRegistration(XssIgnoreFilterUrl url) { FilterRegistrationBean registration = getFilterRegistrationBean(url); return registration; } private FilterRegistrationBean getFilterRegistrationBean(XssIgnoreFilterUrl url) { FilterRegistrationBean registration = new FilterRegistrationBean(); //指定发起请求时过滤 registration.setDispatcherTypes(DispatcherType.REQUEST); registration.setFilter(new XssFilter(Objects.isNull(url) ? null : url.getUrls())); //默认所有接口 registration.addUrlPatterns("/*"); registration.setName("xssFilter"); //设置最后执行,防止有其他过滤器对值需要修改等操作,保证最后过滤字符即可 registration.setOrder(Integer.MAX_VALUE); return registration; } } ``` ## 可配置不过滤地址 ``` /** * xss忽略过滤地址 * * @author LiRui * @version 1.0 */ @Configuration @ConfigurationProperties(prefix = "xss.ignore") public class XssIgnoreFilterUrl { private Set urls; public Set getUrls() { return urls; } public void setUrls(Set urls) { this.urls = urls; } } //yml配置 xss: ignore: urls: - /xss/form ``` ## 主要过滤器代码 ``` /** * XSS过滤 * * @author lirui */ public class XssFilter implements Filter { private Set excludedUris; public XssFilter() { } public XssFilter(Set excludedUris) { this.excludedUris = excludedUris; } /** * 是否排除 * * @param uri * @return */ private boolean isExcludedUri(String uri) { if (CollectionUtils.isEmpty(excludedUris)) { return false; } for (String ex : excludedUris) { if (match(ex, uri)) { return true; } } return false; } /** * 地址匹配 * * @param patternPath * @param requestPath * @return */ public static boolean match(String patternPath, String requestPath) { if (StringUtils.isEmpty(patternPath) || StringUtils.isEmpty(requestPath)) { return false; } PathMatcher matcher = new AntPathMatcher(); return matcher.match(patternPath, requestPath); } @Override public void init(FilterConfig config) throws ServletException { } @Override public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain) throws IOException, ServletException { //可配置多个字符串过滤 XssHttpServletRequestWrapper xssRequest = new XssHttpServletRequestWrapper( (HttpServletRequest) request, new HTMLFilter()); String url = xssRequest.getServletPath(); if (isExcludedUri(url)) { chain.doFilter(request, response); return; } chain.doFilter(xssRequest, response); } @Override public void destroy() { } } ``` > 这里注意match方法,用的Spring包的地址匹配工具,通过匹配地址是否需要过滤 ## xss具体过滤规则 代码较多我就不贴,最后我会上传到gtee仓库。主要注意,renren-fast中如果存在<或者> 单个的,就会自动在求前面或者最后面进行添加另一符号。在过滤时就会删除前面或者后面内容,具体的可以自己试试renrenfast的代码,内容用<或者>一个符号加内容测试就明白了我的意思。 源代码中我将这段代码注释: ``` //自动补充<,> 注释允许传递<>符号 // s = regexReplace(P_BODY_TO_END, "<$1>", s); // s = regexReplace(P_XML_CONTENT, "$1<$2", s); ``` 遇到这种标签,源码中返回的是xxxx,根据业务需求直接返回“”.使用hutool三方包调整代码(仓库中的代码没修改,需要同样需求的自己copy): ``` return HtmlUtil.cleanHtmlTag(HtmlKit.getTextFromHtml(s)); //getTextFromHtml方法源码 public static String getTextFromHtml(String htmlStr) { if (htmlStr == null) { return ""; } else { htmlStr = delHtmlLabel(htmlStr); htmlStr = htmlStr.replaceAll(" ", ""); return htmlStr; } } ``` ## 注意扫描该包(或者加starter也行) @SpringBootApplication(scanBasePackages = {"com.web"}) ## 关于富文本框 开放不做过滤接口配置主要是考虑富文本框的问题,看了很多文章其实主要是处理js脚本,尽量在前端做一次符号转义,然后后端xss攻击过滤器还是需要开启保证安全。