From 27277b51d7deb0ac33a96af660005c73ecb66c3b Mon Sep 17 00:00:00 2001 From: RuoYi Date: Wed, 28 Jul 2021 16:37:56 +0800 Subject: [PATCH] =?UTF-8?q?=E4=BC=98=E5=8C=96XSS=E8=B7=A8=E7=AB=99?= =?UTF-8?q?=E8=84=9A=E6=9C=AC=E8=BF=87=E6=BB=A4?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../com/ruoyi/common/constant/Constants.java | 10 ++ .../com/ruoyi/common/utils/StringUtils.java | 110 +++++++++++++++++- .../java/com/ruoyi/common/xss/XssFilter.java | 33 +----- .../ruoyi/framework/config/FilterConfig.java | 8 +- 4 files changed, 127 insertions(+), 34 deletions(-) diff --git a/ruoyi-common/src/main/java/com/ruoyi/common/constant/Constants.java b/ruoyi-common/src/main/java/com/ruoyi/common/constant/Constants.java index 869997cda..64664e06e 100644 --- a/ruoyi-common/src/main/java/com/ruoyi/common/constant/Constants.java +++ b/ruoyi-common/src/main/java/com/ruoyi/common/constant/Constants.java @@ -17,6 +17,16 @@ public class Constants */ public static final String GBK = "GBK"; + /** + * http请求 + */ + public static final String HTTP = "http://"; + + /** + * https请求 + */ + public static final String HTTPS = "https://"; + /** * 通用成功标识 */ diff --git a/ruoyi-common/src/main/java/com/ruoyi/common/utils/StringUtils.java b/ruoyi-common/src/main/java/com/ruoyi/common/utils/StringUtils.java index 882e94a64..806e4ad9c 100644 --- a/ruoyi-common/src/main/java/com/ruoyi/common/utils/StringUtils.java +++ b/ruoyi-common/src/main/java/com/ruoyi/common/utils/StringUtils.java @@ -1,7 +1,13 @@ package com.ruoyi.common.utils; +import java.util.ArrayList; import java.util.Collection; +import java.util.HashSet; +import java.util.List; import java.util.Map; +import java.util.Set; +import org.springframework.util.AntPathMatcher; +import com.ruoyi.common.constant.Constants; import com.ruoyi.common.core.text.StrFormatter; /** @@ -256,6 +262,68 @@ public class StringUtils extends org.apache.commons.lang3.StringUtils return StrFormatter.format(template, params); } + /** + * 是否为http(s)://开头 + * + * @param link 链接 + * @return 结果 + */ + public static boolean ishttp(String link) + { + return StringUtils.startsWithAny(link, Constants.HTTP, Constants.HTTPS); + } + + /** + * 字符串转set + * + * @param str 字符串 + * @param sep 分隔符 + * @return set集合 + */ + public static final Set str2Set(String str, String sep) + { + return new HashSet(str2List(str, sep, true, false)); + } + + /** + * 字符串转list + * + * @param str 字符串 + * @param sep 分隔符 + * @param filterBlank 过滤纯空白 + * @param trim 去掉首尾空白 + * @return list集合 + */ + public static final List str2List(String str, String sep, boolean filterBlank, boolean trim) + { + List list = new ArrayList(); + if (StringUtils.isEmpty(str)) + { + return list; + } + + // 过滤空白字符串 + if (filterBlank && StringUtils.isBlank(str)) + { + return list; + } + String[] split = str.split(sep); + for (String string : split) + { + if (filterBlank && StringUtils.isBlank(string)) + { + continue; + } + if (trim) + { + string = string.trim(); + } + list.add(string); + } + + return list; + } + /** * 驼峰转下划线命名 */ @@ -301,6 +369,7 @@ public class StringUtils extends org.apache.commons.lang3.StringUtils } sb.append(Character.toLowerCase(c)); } + return sb.toString(); } @@ -400,9 +469,48 @@ public class StringUtils extends org.apache.commons.lang3.StringUtils return sb.toString(); } + /** + * 查找指定字符串是否匹配指定字符串列表中的任意一个字符串 + * + * @param str 指定字符串 + * @param strs 需要检查的字符串数组 + * @return 是否匹配 + */ + public static boolean matches(String str, List strs) + { + if (isEmpty(str) || isEmpty(strs)) + { + return false; + } + for (String pattern : strs) + { + if (isMatch(pattern, str)) + { + return true; + } + } + return false; + } + + /** + * 判断url是否与规则配置: + * ? 表示单个字符; + * * 表示一层路径内的任意字符串,不可跨层级; + * ** 表示任意层路径; + * + * @param pattern 匹配规则 + * @param url 需要匹配的url + * @return + */ + public static boolean isMatch(String pattern, String url) + { + AntPathMatcher matcher = new AntPathMatcher(); + return matcher.match(pattern, url); + } + @SuppressWarnings("unchecked") public static T cast(Object obj) { return (T) obj; } -} +} \ No newline at end of file diff --git a/ruoyi-common/src/main/java/com/ruoyi/common/xss/XssFilter.java b/ruoyi-common/src/main/java/com/ruoyi/common/xss/XssFilter.java index d307fbc9f..30fd69ce8 100644 --- a/ruoyi-common/src/main/java/com/ruoyi/common/xss/XssFilter.java +++ b/ruoyi-common/src/main/java/com/ruoyi/common/xss/XssFilter.java @@ -3,8 +3,6 @@ package com.ruoyi.common.xss; import java.io.IOException; import java.util.ArrayList; import java.util.List; -import java.util.regex.Matcher; -import java.util.regex.Pattern; import javax.servlet.Filter; import javax.servlet.FilterChain; import javax.servlet.FilterConfig; @@ -27,16 +25,10 @@ public class XssFilter implements Filter */ public List 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(","); @@ -45,10 +37,6 @@ public class XssFilter implements Filter excludes.add(url[i]); } } - if (StringUtils.isNotEmpty(tempEnabled)) - { - enabled = Boolean.valueOf(tempEnabled); - } } @Override @@ -68,25 +56,14 @@ public class XssFilter implements Filter private boolean handleExcludeURL(HttpServletRequest request, HttpServletResponse response) { - if (!enabled) + String url = request.getServletPath(); + String method = request.getMethod(); + // GET DELETE 不过滤 + if (method == null || method.matches("GET") || method.matches("DELETE")) { 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; + return StringUtils.matches(url, excludes); } @Override diff --git a/ruoyi-framework/src/main/java/com/ruoyi/framework/config/FilterConfig.java b/ruoyi-framework/src/main/java/com/ruoyi/framework/config/FilterConfig.java index 92d010e80..b7d10b8f9 100644 --- a/ruoyi-framework/src/main/java/com/ruoyi/framework/config/FilterConfig.java +++ b/ruoyi-framework/src/main/java/com/ruoyi/framework/config/FilterConfig.java @@ -4,6 +4,7 @@ import java.util.HashMap; import java.util.Map; import javax.servlet.DispatcherType; import org.springframework.beans.factory.annotation.Value; +import org.springframework.boot.autoconfigure.condition.ConditionalOnProperty; import org.springframework.boot.web.servlet.FilterRegistrationBean; import org.springframework.context.annotation.Bean; import org.springframework.context.annotation.Configuration; @@ -16,11 +17,9 @@ import com.ruoyi.common.xss.XssFilter; * @author ruoyi */ @Configuration +@ConditionalOnProperty(value = "xss.enabled", havingValue = "true") public class FilterConfig { - @Value("${xss.enabled}") - private String enabled; - @Value("${xss.excludes}") private String excludes; @@ -36,10 +35,9 @@ public class FilterConfig registration.setFilter(new XssFilter()); registration.addUrlPatterns(StringUtils.split(urlPatterns, ",")); registration.setName("xssFilter"); - registration.setOrder(Integer.MAX_VALUE); + registration.setOrder(FilterRegistrationBean.HIGHEST_PRECEDENCE); Map initParameters = new HashMap(); initParameters.put("excludes", excludes); - initParameters.put("enabled", enabled); registration.setInitParameters(initParameters); return registration; }