From 6b5dd4d2be69759a8a2452195d0fb0b0ef52e72a Mon Sep 17 00:00:00 2001
From: RuoYi <yzz_ivy@163.com>
Date: Wed, 28 Jul 2021 16:04:59 +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

---
 .../src/main/resources/application.yml        |  2 +-
 .../common/core/domain/entity/SysUser.java    |  2 +-
 .../com/ruoyi/common/filter/XssFilter.java    | 33 +++------------
 .../com/ruoyi/common/utils/StringUtils.java   | 40 +++++++++++++++++++
 .../ruoyi/framework/config/FilterConfig.java  |  6 +--
 5 files changed, 49 insertions(+), 34 deletions(-)

diff --git a/ruoyi-admin/src/main/resources/application.yml b/ruoyi-admin/src/main/resources/application.yml
index 918d354..088a28e 100644
--- a/ruoyi-admin/src/main/resources/application.yml
+++ b/ruoyi-admin/src/main/resources/application.yml
@@ -115,6 +115,6 @@ xss:
   # 过滤开关
   enabled: true
   # 排除链接(多个用逗号分隔)
-  excludes: /system/notice/*
+  excludes: /system/notice
   # 匹配链接
   urlPatterns: /system/*,/monitor/*,/tool/*
diff --git a/ruoyi-common/src/main/java/com/ruoyi/common/core/domain/entity/SysUser.java b/ruoyi-common/src/main/java/com/ruoyi/common/core/domain/entity/SysUser.java
index 7504f02..08cf151 100644
--- a/ruoyi-common/src/main/java/com/ruoyi/common/core/domain/entity/SysUser.java
+++ b/ruoyi-common/src/main/java/com/ruoyi/common/core/domain/entity/SysUser.java
@@ -201,7 +201,7 @@ public class SysUser extends BaseEntity
         this.avatar = avatar;
     }
 
-	@JsonIgnore
+    @JsonIgnore
     @JsonProperty
     public String getPassword()
     {
diff --git a/ruoyi-common/src/main/java/com/ruoyi/common/filter/XssFilter.java b/ruoyi-common/src/main/java/com/ruoyi/common/filter/XssFilter.java
index 1495412..703ce9a 100644
--- a/ruoyi-common/src/main/java/com/ruoyi/common/filter/XssFilter.java
+++ b/ruoyi-common/src/main/java/com/ruoyi/common/filter/XssFilter.java
@@ -3,8 +3,6 @@ package com.ruoyi.common.filter;
 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<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(",");
@@ -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-common/src/main/java/com/ruoyi/common/utils/StringUtils.java b/ruoyi-common/src/main/java/com/ruoyi/common/utils/StringUtils.java
index 72ddb56..ca12798 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
@@ -6,6 +6,7 @@ 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;
 
@@ -463,6 +464,45 @@ public class StringUtils extends org.apache.commons.lang3.StringUtils
         return sb.toString();
     }
 
+    /**
+     * 查找指定字符串是否匹配指定字符串列表中的任意一个字符串
+     * 
+     * @param str 指定字符串
+     * @param strs 需要检查的字符串数组
+     * @return 是否匹配
+     */
+    public static boolean matches(String str, List<String> 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> T cast(Object obj)
     {
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 8b17834..ab12e41 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;
@@ -17,11 +18,9 @@ import com.ruoyi.common.utils.StringUtils;
  * @author ruoyi
  */
 @Configuration
+@ConditionalOnProperty(value = "xss.enabled", havingValue = "true")
 public class FilterConfig
 {
-    @Value("${xss.enabled}")
-    private String enabled;
-
     @Value("${xss.excludes}")
     private String excludes;
 
@@ -40,7 +39,6 @@ public class FilterConfig
         registration.setOrder(FilterRegistrationBean.HIGHEST_PRECEDENCE);
         Map<String, String> initParameters = new HashMap<String, String>();
         initParameters.put("excludes", excludes);
-        initParameters.put("enabled", enabled);
         registration.setInitParameters(initParameters);
         return registration;
     }