瀏覽代碼

fix gitee issues/I3Z2RG SQL 注入判断优化处理

hubin 3 年之前
父節點
當前提交
2ccfa661eb

+ 1 - 1
mybatis-plus-core/src/main/java/com/baomidou/mybatisplus/core/conditions/query/QueryWrapper.java

@@ -99,7 +99,7 @@ public class QueryWrapper<T> extends AbstractWrapper<T, String, QueryWrapper<T>>
 
     @Override
     protected String columnSqlInjectFilter(String column) {
-        return StringUtils.replaceBlank(column);
+        return StringUtils.sqlInjectionReplaceBlank(column);
     }
 
     /**

+ 1 - 1
mybatis-plus-core/src/main/java/com/baomidou/mybatisplus/core/conditions/update/UpdateWrapper.java

@@ -93,7 +93,7 @@ public class UpdateWrapper<T> extends AbstractWrapper<T, String, UpdateWrapper<T
 
     @Override
     protected String columnSqlInjectFilter(String column) {
-        return StringUtils.replaceBlank(column);
+        return StringUtils.sqlInjectionReplaceBlank(column);
     }
 
     /**

+ 11 - 6
mybatis-plus-core/src/main/java/com/baomidou/mybatisplus/core/toolkit/StringUtils.java

@@ -15,11 +15,11 @@
  */
 package com.baomidou.mybatisplus.core.toolkit;
 
+import com.baomidou.mybatisplus.core.toolkit.sql.SqlInjectionUtils;
 import com.baomidou.mybatisplus.core.toolkit.sql.StringEscape;
 import com.baomidou.mybatisplus.core.toolkit.support.BiIntFunction;
 
 import java.util.Collection;
-import java.util.Objects;
 import java.util.regex.Matcher;
 import java.util.regex.Pattern;
 
@@ -577,7 +577,7 @@ public final class StringUtils {
     }
 
     /**
-     * 字符串去除空白内容:
+     * SQL 注入字符串去除空白内容:
      * <ul>
      *     <li>\n 回车</li>
      *     <li>\t 水平制表符</li>
@@ -587,9 +587,14 @@ public final class StringUtils {
      *
      * @param str 字符串
      */
-    public static String replaceBlank(String str) {
-        Objects.requireNonNull(str);
-        Matcher matcher = REPLACE_BLANK.matcher(str);
-        return matcher.replaceAll("");
+    public static String sqlInjectionReplaceBlank(String str) {
+        if (SqlInjectionUtils.check(str)) {
+            /**
+             * 存在 SQL 注入,去除空白内容
+             */
+            Matcher matcher = REPLACE_BLANK.matcher(str);
+            return matcher.replaceAll("");
+        }
+        return str;
     }
 }

+ 52 - 0
mybatis-plus-core/src/main/java/com/baomidou/mybatisplus/core/toolkit/sql/SqlInjectionUtils.java

@@ -0,0 +1,52 @@
+/*
+ * Copyright (c) 2011-2021, baomidou (jobob@qq.com).
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package com.baomidou.mybatisplus.core.toolkit.sql;
+
+import java.util.Objects;
+import java.util.regex.Pattern;
+
+/**
+ * SQL 注入验证工具类
+ *
+ * @author hubin
+ * @since 2021-08-15
+ */
+public class SqlInjectionUtils {
+    // SQL语法检查正则:符合两个关键字(有先后顺序)才算匹配
+    private static final Pattern sqlSyntaxPattern = Pattern.compile("(insert|delete|update|select|create|drop|truncate|grant|alter|deny|revoke|call|execute|exec|declare|show|rename|set)" +
+        ".+(into|from|set|where|table|database|view|index|on|cursor|procedure|trigger|for|password|union|and|or)", Pattern.CASE_INSENSITIVE);
+    // 使用'、;或注释截断SQL检查正则
+    private static final Pattern sqlCommentPattern = Pattern.compile("'.*(or|union|--|#|/*|;)", Pattern.CASE_INSENSITIVE);
+
+    /**
+     * 检查参数是否存在 SQL 注入
+     *
+     * @param value 检查参数
+     * @return true 非法 false 合法
+     */
+    public static boolean check(String value) {
+        Objects.requireNonNull(value);
+        // 处理是否包含SQL注释字符
+        if (sqlCommentPattern.matcher(value).find()) {
+            return true;
+        }
+        // 检查是否包含SQL注入敏感字符
+        if (sqlSyntaxPattern.matcher(value).find()) {
+            return true;
+        }
+        return false;
+    }
+}

+ 31 - 0
mybatis-plus-core/src/test/java/com/baomidou/mybatisplus/core/toolkit/sql/SqlInjectionUtilsTest.java

@@ -0,0 +1,31 @@
+package com.baomidou.mybatisplus.core.toolkit.sql;
+
+import org.junit.jupiter.api.Assertions;
+import org.junit.jupiter.api.Test;
+
+/**
+ * SQL 注入验证工具类测试
+ *
+ * @author hubin
+ * @since 2021-08-15
+ */
+public class SqlInjectionUtilsTest {
+
+    @Test
+    public void sqlTest() {
+        assertSql(false, "insert abc");
+        assertSql(true, "insert user (id,name) value (1, 'qm')");
+        assertSql(true, "select * from user");
+        assertSql(true, "delete from user");
+        assertSql(true, "drop table user");
+        assertSql(true, ";truncate from user");
+        assertSql(false, "update");
+        assertSql(false, "trigger");
+        assertSql(true, "and name like '%s123%s'");
+        assertSql(false, "convert(name using GBK)");
+    }
+
+    private void assertSql(boolean injection, String sql) {
+        Assertions.assertEquals(injection, SqlInjectionUtils.check(sql));
+    }
+}