浏览代码

完善 SqlInjectionUtils.check 注入校验方法覆盖 UpdateWrapper 条件 checkSqlInjection() 注入检测方法

hubin 1 年之前
父节点
当前提交
1c5ef2cfb6

+ 3 - 3
README-zh.md

@@ -31,11 +31,11 @@ Mybatis 增强工具包 - 只做增强不做改变,简化`CRUD`操作
 # 特别用户
 
 <p>
-  <a href="https://flowlong.gitee.io/docs/preface.html?from=mp" target="_blank">
-   <img alt="AiZuDa-Logo" src="https://baomidou.com/img/azd01.png" width="160px" height="50px">
+  <a href="https://doc.flowlong.com?from=mp" target="_blank">
+   <img alt="AiZuDa-Logo" src="https://foruda.gitee.com/images/1715955628416785121/954c16ef_12260.png" width="160px" height="50px">
   </a>
   <a href="https://gitee.com/gz-yami/mall4j?from=mp" target="_blank">
-   <img alt="Mybatis-Plus-Logo" src="https://baomidou.com/img/mall4j.gif" width="160px" height="50px">
+   <img alt="Mybatis-Plus-Logo" src="https://foruda.gitee.com/images/1716599753022423252/fb0139cf_12260.png" width="160px" height="50px">
   </a>
   <a href="http://github.crmeb.net/u/MyBatis-Plus" target="_blank">
    <img alt="Crmeb-Logo" src="https://foruda.gitee.com/images/1685339553088166856/b0a6b1a4_12260.gif" width="160px" height="50px">

+ 3 - 3
README.md

@@ -31,11 +31,11 @@
 # Special user
 
 <p>
-  <a href="https://flowlong.gitee.io/docs/preface.html?from=mp" target="_blank">
-   <img alt="AiZuDa-Logo" src="https://baomidou.com/img/azd01.png" width="160px" height="50px">
+  <a href="https://doc.flowlong.com?from=mp" target="_blank">
+   <img alt="AiZuDa-Logo" src="https://foruda.gitee.com/images/1715955628416785121/954c16ef_12260.png" width="160px" height="50px">
   </a>
   <a href="https://gitee.com/gz-yami/mall4j?from=mp" target="_blank">
-   <img alt="Mybatis-Plus-Logo" src="https://baomidou.com/img/mall4j.gif" width="160px" height="50px">
+   <img alt="Mybatis-Plus-Logo" src="https://foruda.gitee.com/images/1716599753022423252/fb0139cf_12260.png" width="160px" height="50px">
   </a>
 </p>
 

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

@@ -18,9 +18,11 @@ package com.baomidou.mybatisplus.core.conditions.update;
 import com.baomidou.mybatisplus.core.conditions.AbstractWrapper;
 import com.baomidou.mybatisplus.core.conditions.SharedString;
 import com.baomidou.mybatisplus.core.conditions.segments.MergeSegments;
+import com.baomidou.mybatisplus.core.exceptions.MybatisPlusException;
 import com.baomidou.mybatisplus.core.toolkit.CollectionUtils;
 import com.baomidou.mybatisplus.core.toolkit.Constants;
 import com.baomidou.mybatisplus.core.toolkit.StringUtils;
+import com.baomidou.mybatisplus.core.toolkit.sql.SqlInjectionUtils;
 
 import java.util.ArrayList;
 import java.util.List;
@@ -66,6 +68,28 @@ public class UpdateWrapper<T> extends AbstractWrapper<T, String, UpdateWrapper<T
         this.sqlFirst = sqlFirst;
     }
 
+
+    /**
+     * 检查 SQL 注入过滤
+     */
+    private boolean checkSqlInjection;
+
+    /**
+     * 开启检查 SQL 注入
+     */
+    public UpdateWrapper<T> checkSqlInjection() {
+        this.checkSqlInjection = true;
+        return this;
+    }
+
+    @Override
+    protected String columnToString(String column) {
+        if (checkSqlInjection && SqlInjectionUtils.check(column)) {
+            throw new MybatisPlusException("Discovering SQL injection column: " + column);
+        }
+        return column;
+    }
+
     @Override
     public String getSqlSet() {
         if (CollectionUtils.isEmpty(sqlSet)) {

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

@@ -29,7 +29,7 @@ public class SqlInjectionUtils {
      * SQL语法检查正则:符合两个关键字(有先后顺序)才算匹配
      */
     private static final Pattern SQL_SYNTAX_PATTERN = Pattern.compile("(insert|delete|update|select|create|drop|truncate|grant|alter|deny|revoke|call|execute|exec|declare|show|rename|set)" +
-        "\\s+.*(into|from|set|where|table|database|view|index|on|cursor|procedure|trigger|for|password|union|and|or)|(select\\s*\\*\\s*from\\s+)|(and|or)\\s+.*(like|=|>|<|in|between|is|not|exists)", Pattern.CASE_INSENSITIVE);
+        "\\s+.*(into|from|set|where|table|database|view|index|on|cursor|procedure|trigger|for|password|union|and|or)|(select\\s*\\*\\s*from\\s+)|(and|or)\\s+.*", Pattern.CASE_INSENSITIVE);
     /**
      * 使用'、;或注释截断SQL检查正则
      */

+ 4 - 1
mybatis-plus-core/src/test/java/com/baomidou/mybatisplus/core/conditions/UpdateWrapperTest.java

@@ -1,7 +1,9 @@
 package com.baomidou.mybatisplus.core.conditions;
 
 import com.baomidou.mybatisplus.core.conditions.update.UpdateWrapper;
+import com.baomidou.mybatisplus.core.exceptions.MybatisPlusException;
 import com.baomidou.mybatisplus.test.User;
+import org.junit.jupiter.api.Assertions;
 import org.junit.jupiter.api.Test;
 
 /**
@@ -12,7 +14,7 @@ class UpdateWrapperTest extends BaseWrapperTest {
 
     @Test
     void test1() {
-        UpdateWrapper<User> wrapper = new UpdateWrapper<User>()
+        UpdateWrapper<User> wrapper = new UpdateWrapper<User>().checkSqlInjection().eq("hi=1 or a", 123)
             .set("name", "a", "typeHandler=org.apache.ibatis.type.StringTypeHandler")
             .set("name", "a", "typeHandler=org.apache.ibatis.type.StringTypeHandler,jdbcType=VARCHAR")
             .set("name", "a", "typeHandler=org.apache.ibatis.type.StringTypeHandler,jdbcType=VARCHAR,numericScale=2");
@@ -21,5 +23,6 @@ class UpdateWrapperTest extends BaseWrapperTest {
                 "name=#{ew.paramNameValuePairs.MPGENVAL2,typeHandler=org.apache.ibatis.type.StringTypeHandler,jdbcType=VARCHAR}," +
                 "name=#{ew.paramNameValuePairs.MPGENVAL3,typeHandler=org.apache.ibatis.type.StringTypeHandler,jdbcType=VARCHAR,numericScale=2}");
         logParams(wrapper);
+        Assertions.assertThrows(MybatisPlusException.class, wrapper::getSqlSegment);
     }
 }

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

@@ -55,6 +55,11 @@ import org.junit.jupiter.api.Test;
         assertSql(false,"ORDER BY field(status,'SUCCESS','FAILED','CLOSED')");
         assertSql(true,"ORDER BY id,'SUCCESS',''-- FAILED','CLOSED'");
         assertSql(true, "or 1 = 1");
+        assertSql(true, "and 1 = 1");
+        assertSql(true, "hi = 1 or abc");
+        assertSql(true, "(hi = 1) and abc");
+        assertSql(false, "orAnd");
+        assertSql(false, "andOr");
     }
 
     private void assertSql(boolean injection, String sql) {