From f9f8cce13e0a91809357590cec3ae2ca4a5a8f6f Mon Sep 17 00:00:00 2001 From: Chopper Date: Mon, 7 Jun 2021 15:00:36 +0800 Subject: [PATCH] =?UTF-8?q?xss=E9=98=B2=E5=BE=A1=E7=9B=B8=E5=85=B3?= =?UTF-8?q?=E6=9B=B4=E6=94=B9=E7=AD=96=E7=95=A5=EF=BC=8C=E8=B0=83=E6=95=B4?= =?UTF-8?q?=E4=BB=A3=E7=A0=81?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../XssAndSqlHttpServletRequestWrapper.java | 46 ------ .../common/security/filter/XssFilter.java | 33 +---- .../filter/XssHttpServletRequestWrapper.java | 136 ++++++++++++++++++ .../filter/XssStringJsonSerializer.java | 32 ----- 4 files changed, 142 insertions(+), 105 deletions(-) delete mode 100644 framework/src/main/java/cn/lili/common/security/filter/XssAndSqlHttpServletRequestWrapper.java create mode 100644 framework/src/main/java/cn/lili/common/security/filter/XssHttpServletRequestWrapper.java delete mode 100644 framework/src/main/java/cn/lili/common/security/filter/XssStringJsonSerializer.java diff --git a/framework/src/main/java/cn/lili/common/security/filter/XssAndSqlHttpServletRequestWrapper.java b/framework/src/main/java/cn/lili/common/security/filter/XssAndSqlHttpServletRequestWrapper.java deleted file mode 100644 index 37e96de8..00000000 --- a/framework/src/main/java/cn/lili/common/security/filter/XssAndSqlHttpServletRequestWrapper.java +++ /dev/null @@ -1,46 +0,0 @@ -package cn.lili.common.security.filter; - - -import org.apache.commons.lang3.StringUtils; -import org.apache.commons.text.StringEscapeUtils; - -import javax.servlet.http.HttpServletRequest; -import javax.servlet.http.HttpServletRequestWrapper; - -/** - * 防止Xss sql注入 - * - * @author Chopper - * @version v1.0 - * 2021-06-04 10:39 - */ -public class XssAndSqlHttpServletRequestWrapper extends HttpServletRequestWrapper { - private HttpServletRequest request; - - public XssAndSqlHttpServletRequestWrapper(HttpServletRequest request) { - super(request); - this.request = request; - } - - @Override - public String getParameter(String name) { - String value = request.getParameter(name); - if (!StringUtils.isEmpty(value)) { - value = StringEscapeUtils.escapeHtml4(value); - } - return value; - } - - @Override - public String[] getParameterValues(String name) { - String[] parameterValues = super.getParameterValues(name); - if (parameterValues == null) { - return null; - } - for (int i = 0; i < parameterValues.length; i++) { - String value = parameterValues[i]; - parameterValues[i] = StringEscapeUtils.escapeHtml4(value); - } - return parameterValues; - } -} diff --git a/framework/src/main/java/cn/lili/common/security/filter/XssFilter.java b/framework/src/main/java/cn/lili/common/security/filter/XssFilter.java index 97433044..ead0a2b1 100644 --- a/framework/src/main/java/cn/lili/common/security/filter/XssFilter.java +++ b/framework/src/main/java/cn/lili/common/security/filter/XssFilter.java @@ -1,11 +1,6 @@ package cn.lili.common.security.filter; -import com.fasterxml.jackson.databind.ObjectMapper; -import com.fasterxml.jackson.databind.module.SimpleModule; -import org.springframework.context.annotation.Bean; -import org.springframework.context.annotation.Primary; -import org.springframework.http.converter.json.Jackson2ObjectMapperBuilder; import org.springframework.stereotype.Component; import javax.servlet.*; @@ -23,38 +18,22 @@ import java.io.IOException; @WebFilter @Component public class XssFilter implements Filter { + FilterConfig filterConfig = null; + @Override public void init(FilterConfig filterConfig) throws ServletException { + this.filterConfig = filterConfig; } @Override public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain) throws IOException, ServletException { - HttpServletRequest req = (HttpServletRequest) request; - XssAndSqlHttpServletRequestWrapper xssRequestWrapper = new XssAndSqlHttpServletRequestWrapper(req); - chain.doFilter(xssRequestWrapper, response); + //对请求进行拦截,防xss处理 + chain.doFilter(new XssHttpServletRequestWrapper((HttpServletRequest) request), response); } @Override public void destroy() { - } - - /** - * 过滤json类型的 - * - * @param builder - * @return - */ - @Bean - @Primary - public ObjectMapper xssObjectMapper(Jackson2ObjectMapperBuilder builder) { - //解析器 - ObjectMapper objectMapper = builder.createXmlMapper(false).build(); - //注册xss解析器 - SimpleModule xssModule = new SimpleModule("XssStringJsonSerializer"); - xssModule.addSerializer(new XssStringJsonSerializer()); - objectMapper.registerModule(xssModule); - //返回 - return objectMapper; + this.filterConfig = null; } } diff --git a/framework/src/main/java/cn/lili/common/security/filter/XssHttpServletRequestWrapper.java b/framework/src/main/java/cn/lili/common/security/filter/XssHttpServletRequestWrapper.java new file mode 100644 index 00000000..70c2df5b --- /dev/null +++ b/framework/src/main/java/cn/lili/common/security/filter/XssHttpServletRequestWrapper.java @@ -0,0 +1,136 @@ +package cn.lili.common.security.filter; + + +import javax.servlet.http.HttpServletRequest; +import javax.servlet.http.HttpServletRequestWrapper; +import java.util.regex.Pattern; + +/** + * 防止Xss sql注入 + * + * @author Chopper + * @version v1.0 + * 2021-06-04 10:39 + */ +public class XssHttpServletRequestWrapper extends HttpServletRequestWrapper { + private HttpServletRequest request; + + public XssHttpServletRequestWrapper(HttpServletRequest request) { + super(request); + this.request = request; + } + + /** + * 对数组参数进行特殊字符过滤 + */ + @Override + public String[] getParameterValues(String name) { + String[] values = super.getParameterValues(name); + if (values == null) { + return null; + } + int count = values.length; + String[] encodedValues = new String[count]; + for (int i = 0; i < count; i++) { + encodedValues[i] = cleanXSS(values[i]); + } + return encodedValues; + } + + /** + * 对参数中特殊字符进行过滤 + */ + @Override + public String getParameter(String name) { + String value = super.getParameter(name); + if (value == null) { + return null; + } + return cleanXSS(value); + } + + /** + * 获取attribute,特殊字符过滤 + */ + @Override + public Object getAttribute(String name) { + Object value = super.getAttribute(name); + if (value != null && value instanceof String) { + cleanXSS((String) value); + } + return value; + } + + /** + * 对请求头部进行特殊字符过滤 + */ + @Override + public String getHeader(String name) { + String value = super.getHeader(name); + if (value == null) { + return null; + } + return cleanXSS(value); + } + + /** + * 转义字符,使用该方法存在一定的弊端 + * + * @param value + * @return + */ + private String cleanXSS2(String value) { + // 移除特殊标签 + value = value.replaceAll("<", "<").replaceAll(">", ">"); + value = value.replaceAll("\\(", "(").replaceAll("\\)", ")"); + value = value.replaceAll("'", "'"); + value = value.replaceAll("eval\\((.*)\\)", ""); + value = value.replaceAll("[\\\"\\\'][\\s]*javascript:(.*)[\\\"\\\']", "\"\""); + value = value.replaceAll("script", ""); + return value; + } + + private String cleanXSS(String value) { + if (value != null) { + //推荐使用ESAPI库来避免脚本攻击,value = ESAPI.encoder().canonicalize(value); + // 避免空字符串 + value = value.replaceAll(" ", ""); + // 避免script 标签 + Pattern scriptPattern = Pattern.compile("", Pattern.CASE_INSENSITIVE); + value = scriptPattern.matcher(value).replaceAll(""); + // 避免src形式的表达式 + scriptPattern = Pattern.compile("src[\r\n]*=[\r\n]*\\\'(.*?)\\\'", + Pattern.CASE_INSENSITIVE | Pattern.MULTILINE | Pattern.DOTALL); + value = scriptPattern.matcher(value).replaceAll(""); + scriptPattern = Pattern.compile("src[\r\n]*=[\r\n]*\\\"(.*?)\\\"", + Pattern.CASE_INSENSITIVE | Pattern.MULTILINE | Pattern.DOTALL); + value = scriptPattern.matcher(value).replaceAll(""); + // 删除单个的 标签 + scriptPattern = Pattern.compile("", Pattern.CASE_INSENSITIVE); + value = scriptPattern.matcher(value).replaceAll(""); + // 删除单个的