Browse Source

feat(security): 添加安全过滤器配置并优化SQL注入检测

- 在多个环境配置文件中添加安全过滤器配置项
- 启用XSS防护和SQL注入防护功能
- 配置排除不需要检查的URL路径
- 设置需要检查的请求头列表
- 优化SQL注入检测逻辑,增加正常User-Agent判断
- 移除恶意HTTP请求异常类及相应异常处理器
- 修改安全过滤器使用JeecgBootException替代BadHttpRequestException
- 调整组件扫描范围确保安全配置生效
wzq 4 days ago
parent
commit
65326a407a

+ 0 - 22
national-motion-base-core/src/main/java/org/jeecg/common/exception/BadHttpRequestException.java

@@ -1,22 +0,0 @@
-package org.jeecg.common.exception;
-
-import lombok.Getter;
-
-/**
- * 恶意HTTP请求异常
- * <p>
- * 用于标识XSS攻击、SQL注入等恶意请求
- * 
- * @author zsElectric
- */
-@Getter
-public class BadHttpRequestException extends RuntimeException {
-
-    public BadHttpRequestException(String message) {
-        super(message);
-    }
-
-    public BadHttpRequestException(String message, Throwable cause) {
-        super(message, cause);
-    }
-}

+ 0 - 11
national-motion-base-core/src/main/java/org/jeecg/common/exception/JeecgBootExceptionHandler.java

@@ -204,17 +204,6 @@ public class JeecgBootExceptionHandler {
         return Result.error("Redis 连接异常!");
     }
 
-    /**
-     * 处理恶意HTTP请求异常(XSS攻击、SQL注入等)
-     * 当检测到恶意请求时,会抛出 BadHttpRequestException 异常。
-     */
-    @ExceptionHandler(BadHttpRequestException.class)
-    @ResponseStatus(HttpStatus.BAD_REQUEST)
-    public <T> Result<T> handleBadHttpRequestException(BadHttpRequestException e) {
-        log.error("检测到恶意请求,异常原因:{}", e.getMessage(), e);
-        return Result.error("用户输入包含非法内容,请输入合法内容!");
-    }
-
 
 	/**
 	 * SQL注入风险,全局异常处理

+ 35 - 0
national-motion-base-core/src/main/java/org/jeecg/common/util/SecurityUtils.java

@@ -267,6 +267,11 @@ public class SecurityUtils {
      * @return 如果是真实攻击返回 true,否则返回 false
      */
     private static boolean isRealSqlInjection(String keyword, String value) {
+        // 首先检查是否为正常的User-Agent或其他合法字符串
+        if (isNormalUserAgent(value)) {
+            return false;
+        }
+        
         if (!sqlStrictMode) {
             // 在宽松模式下,只对明显的攻击模式进行拦截
             switch (keyword) {
@@ -377,4 +382,34 @@ public class SecurityUtils {
             }
         }
     }
+    
+    /**
+     * 判断是否为正常的User-Agent字符串
+     * 
+     * @param value 待检测的字符串
+     * @return 如果是正常User-Agent返回true,否则返回false
+     */
+    private static boolean isNormalUserAgent(String value) {
+        // 检查是否包含典型的浏览器User-Agent特征
+        if (value.contains("mozilla/") || value.contains("chrome/") || value.contains("safari/") || 
+            value.contains("firefox/") || value.contains("edge/") || value.contains("opera/") ||
+            value.contains("mobile") || value.contains("android") || value.contains("iphone") ||
+            value.contains("ipad") || value.contains("macintosh") || value.contains("windows")) {
+            return true;
+        }
+        
+        // 检查是否包含常见的爬虫User-Agent特征
+        if (value.contains("bot") || value.contains("crawler") || value.contains("spider") ||
+            value.contains("google") || value.contains("bing") || value.contains("baidu")) {
+            return true;
+        }
+        
+        // 检查是否包含常见的库或框架User-Agent特征
+        if (value.contains("axios") || value.contains("okhttp") || value.contains("java") ||
+            value.contains("python") || value.contains("curl") || value.contains("wget")) {
+            return true;
+        }
+        
+        return false;
+    }
 }

+ 6 - 6
national-motion-base-core/src/main/java/org/jeecg/config/filter/XssAndSqlInjectionFilter.java

@@ -5,7 +5,7 @@ import cn.hutool.core.util.StrUtil;
 
 import lombok.extern.slf4j.Slf4j;
 import org.jeecg.common.constant.SecurityFilterProperties;
-import org.jeecg.common.exception.BadHttpRequestException;
+import org.jeecg.common.exception.JeecgBootException;
 import org.jeecg.common.util.SecurityUtils;
 import org.springframework.http.HttpHeaders;
 import org.springframework.http.MediaType;
@@ -55,7 +55,6 @@ public class XssAndSqlInjectionFilter implements Filter {
      * 默认需要检查的请求头
      */
     private static final Set<String> DEFAULT_CHECK_HEADERS = new HashSet<>(Arrays.asList(
-            "User-Agent",
             "Referer",
             "X-Forwarded-For"
     ));
@@ -80,9 +79,9 @@ public class XssAndSqlInjectionFilter implements Filter {
             // 包装请求,进行安全检查
             SecurityRequestWrapper wrappedRequest = new SecurityRequestWrapper(httpRequest);
             chain.doFilter(wrappedRequest, response);
-        } catch (BadHttpRequestException e) {
+        } catch (Exception e) {
             log.error("检测到恶意请求,URL: {}, 错误信息: {}", httpRequest.getRequestURI(), e.getMessage());
-            throw e;
+            throw new JeecgBootException("用户输入包含非法内容,请输入合法内容!");
         }
     }
 
@@ -229,12 +228,13 @@ public class XssAndSqlInjectionFilter implements Filter {
         private void checkContent(String content, String location) {
             // XSS 检测
             if (properties.getXssEnabled() && SecurityUtils.containsXss(content)) {
-                throw new BadHttpRequestException("检测到 XSS 攻击尝试,位置: " + location);
+//                throw new JeecgBootException("检测到 XSS 攻击尝试,位置: " + location);
+                throw new JeecgBootException("用户输入包含非法内容,请输入合法内容!");
             }
 
             // SQL 注入检测
             if (properties.getSqlInjectionEnabled() && SecurityUtils.containsSqlInjection(content)) {
-                throw new BadHttpRequestException("检测到 SQL 注入尝试,位置: " + location);
+                throw new JeecgBootException("用户输入包含非法内容,请输入合法内容!");
             }
         }
 

+ 2 - 0
national-motion-module-system/national-motion-system-start/src/main/java/org/jeecg/JeecgSystemApplication.java

@@ -10,6 +10,7 @@ import org.springframework.boot.builder.SpringApplicationBuilder;
 import org.springframework.boot.web.servlet.support.SpringBootServletInitializer;
 import org.springframework.cache.CacheManager;
 import org.springframework.context.ConfigurableApplicationContext;
+import org.springframework.context.annotation.ComponentScan;
 import org.springframework.core.env.Environment;
 
 import java.net.InetAddress;
@@ -22,6 +23,7 @@ import java.util.Map;
 */
 @Slf4j
 @SpringBootApplication
+@ComponentScan(basePackages = {"org.jeecg", "org.jeecg.common", "org.jeecg.config"}) // 确保扫描到所有必要的包
 public class JeecgSystemApplication extends SpringBootServletInitializer {
 
     @Override

+ 22 - 0
national-motion-module-system/national-motion-system-start/src/main/resources/application-dev.yml

@@ -412,6 +412,28 @@ http:
     validate:
       after_inactivity: 30000
 
+# 安全过滤器配置
+security:
+  filter:
+    # 启用XSS防护
+    xss-enabled: true
+    # 启用SQL注入防护
+    sql-injection-enabled: true
+    # SQL注入检测使用宽松模式,减少误判
+    sql-strict-mode: false
+    # 排除不需要检查的URL路径
+    exclude-urls:
+      - /doc.html
+      - /swagger-ui
+      - /v3/api-docs
+      - /webjars
+    # 检查的请求头列表
+    check-headers:
+      - Referer
+      - X-Forwarded-For
+      # 注释掉User-Agent,避免误判正常的浏览器标识
+      # - User-Agent
+
 # 异步线程池配置
 async:
   thread-pool:

+ 22 - 0
national-motion-module-system/national-motion-system-start/src/main/resources/application-dm8.yml

@@ -282,3 +282,25 @@ justauth:
     type: default
     prefix: 'demo::'
     timeout: 1h
+
+# 安全过滤器配置
+security:
+  filter:
+    # 启用XSS防护
+    xss-enabled: true
+    # 启用SQL注入防护
+    sql-injection-enabled: true
+    # SQL注入检测使用宽松模式,减少误判
+    sql-strict-mode: false
+    # 排除不需要检查的URL路径
+    exclude-urls:
+      - /doc.html
+      - /swagger-ui
+      - /v3/api-docs
+      - /webjars
+    # 检查的请求头列表
+    check-headers:
+      - Referer
+      - X-Forwarded-For
+      # 注释掉User-Agent,避免误判正常的浏览器标识
+      # - User-Agent

+ 22 - 0
national-motion-module-system/national-motion-system-start/src/main/resources/application-kingbase8.yml

@@ -296,3 +296,25 @@ justauth:
     type: default
     prefix: 'demo::'
     timeout: 1h
+
+# 安全过滤器配置
+security:
+  filter:
+    # 启用XSS防护
+    xss-enabled: true
+    # 启用SQL注入防护
+    sql-injection-enabled: true
+    # SQL注入检测使用宽松模式,减少误判
+    sql-strict-mode: false
+    # 排除不需要检查的URL路径
+    exclude-urls:
+      - /doc.html
+      - /swagger-ui
+      - /v3/api-docs
+      - /webjars
+    # 检查的请求头列表
+    check-headers:
+      - Referer
+      - X-Forwarded-For
+      # 注释掉User-Agent,避免误判正常的浏览器标识
+      # - User-Agent

+ 21 - 1
national-motion-module-system/national-motion-system-start/src/main/resources/application-prod.yml

@@ -423,4 +423,24 @@ http:
       max:
         per_route: 50
     validate:
-      after_inactivity: 30000
+      after_inactivity: 30000
+
+# 安全过滤器配置
+security:
+  filter:
+    # 启用XSS防护
+    xss-enabled: true
+    # 启用SQL注入防护
+    sql-injection-enabled: true
+    # SQL注入检测使用宽松模式,减少误判
+    sql-strict-mode: false
+    # 排除不需要检查的URL路径
+    exclude-urls:
+      - /doc.html
+      - /swagger-ui
+      - /v3/api-docs
+      - /webjars
+    # 检查的请求头列表
+    check-headers:
+      - Referer
+      - X-Forwarded-For

+ 22 - 0
national-motion-module-system/national-motion-system-start/src/main/resources/application-test.yml

@@ -326,3 +326,25 @@ justauth:
     type: default
     prefix: 'demo::'
     timeout: 1h
+
+# 安全过滤器配置
+security:
+  filter:
+    # 启用XSS防护
+    xss-enabled: true
+    # 启用SQL注入防护
+    sql-injection-enabled: true
+    # SQL注入检测使用宽松模式,减少误判
+    sql-strict-mode: false
+    # 排除不需要检查的URL路径
+    exclude-urls:
+      - /doc.html
+      - /swagger-ui
+      - /v3/api-docs
+      - /webjars
+    # 检查的请求头列表
+    check-headers:
+      - Referer
+      - X-Forwarded-For
+      # 注释掉User-Agent,避免误判正常的浏览器标识
+      # - User-Agent