Browse Source

Merge pull request #2935 from liuxx001/3.0

fix #2930 BlockAttackInnerInterceptor 很容易被攻击SQL绕过的问题
miemieYaho 4 years ago
parent
commit
03df0e99b4

+ 26 - 7
mybatis-plus-extension/src/main/java/com/baomidou/mybatisplus/extension/plugins/inner/BlockAttackInnerInterceptor.java

@@ -20,10 +20,13 @@ import com.baomidou.mybatisplus.core.toolkit.Assert;
 import com.baomidou.mybatisplus.core.toolkit.PluginUtils;
 import com.baomidou.mybatisplus.extension.parser.JsqlParserSupport;
 import net.sf.jsqlparser.expression.Expression;
+import net.sf.jsqlparser.expression.operators.conditional.AndExpression;
+import net.sf.jsqlparser.expression.operators.conditional.OrExpression;
 import net.sf.jsqlparser.expression.operators.relational.EqualsTo;
 import net.sf.jsqlparser.expression.operators.relational.NotEqualsTo;
 import net.sf.jsqlparser.statement.delete.Delete;
 import net.sf.jsqlparser.statement.update.Update;
+import org.apache.commons.lang3.StringUtils;
 import org.apache.ibatis.executor.statement.StatementHandler;
 import org.apache.ibatis.mapping.BoundSql;
 import org.apache.ibatis.mapping.MappedStatement;
@@ -62,19 +65,35 @@ public class BlockAttackInnerInterceptor extends JsqlParserSupport implements In
     }
 
     protected void checkWhere(Expression where, String ex) {
-        Assert.notNull(where, ex);
+        Assert.isFalse(this.fullMatch(where), ex);
+    }
+
+    private boolean fullMatch(Expression where) {
+        if (where == null) {
+            return true;
+        }
         if (where instanceof EqualsTo) {
             // example: 1=1
             EqualsTo equalsTo = (EqualsTo) where;
-            Expression leftExpression = equalsTo.getLeftExpression();
-            Expression rightExpression = equalsTo.getRightExpression();
-            Assert.isFalse(leftExpression.toString().equals(rightExpression.toString()), ex);
+            return StringUtils.equals(equalsTo.getLeftExpression().toString(), equalsTo.getRightExpression().toString());
         } else if (where instanceof NotEqualsTo) {
             // example: 1 != 2
             NotEqualsTo notEqualsTo = (NotEqualsTo) where;
-            Expression leftExpression = notEqualsTo.getLeftExpression();
-            Expression rightExpression = notEqualsTo.getRightExpression();
-            Assert.isTrue(leftExpression.toString().equals(rightExpression.toString()), ex);
+            return !StringUtils.equals(notEqualsTo.getLeftExpression().toString(), notEqualsTo.getRightExpression().toString());
+        } else if (where instanceof OrExpression) {
+
+            OrExpression orExpression = (OrExpression) where;
+            return fullMatch(orExpression.getLeftExpression()) || fullMatch(orExpression.getRightExpression());
+        } else if (where instanceof AndExpression) {
+
+            AndExpression andExpression = (AndExpression) where;
+            return fullMatch(andExpression.getLeftExpression()) && fullMatch(andExpression.getRightExpression());
+        } else if (where instanceof Parenthesis) {
+            // example: (1 = 1)
+            Parenthesis parenthesis = (Parenthesis) where;
+            return fullMatch(parenthesis.getExpression());
         }
+
+        return false;
     }
 }

+ 7 - 2
mybatis-plus-extension/src/test/java/com/baomidou/mybatisplus/extension/plugins/inner/BlockAttackInnerInterceptorTest.java

@@ -19,7 +19,11 @@ class BlockAttackInnerInterceptorTest {
         checkEx("update user set name = null where 1=1", "1=1");
         checkEx("update user set name = null where 1<>2", "1<>2");
         checkEx("update user set name = null where 1!=2", "1!=2");
-//        check("update user set name = null where 1=1 and 2=2", "1=1 and 2=2");
+        checkEx("update user set name = null where 1=1 and 2=2", "1=1 and 2=2");
+        checkEx("update user set name = null where 1=1 and 2=3 or 1=1", "1=1 and 2=3 or 1=1");
+        checkEx("update user set name = null where 1=1 and (2=2)", "1=1 and (2=2)");
+        checkEx("update user set name = null where (1=1 and 2=2)", "(1=1 and 2=2)");
+        checkEx("update user set name = null where (1=1 and (2=3 or 3=3))", "(1=1 and (2=3 or 3=3))");
 
         checkNotEx("update user set name = null where 1=?", "1=?");
     }
@@ -30,7 +34,8 @@ class BlockAttackInnerInterceptorTest {
         checkEx("delete from user where 1=1", "1=1");
         checkEx("delete from user where 1<>2", "1<>2");
         checkEx("delete from user where 1!=2", "1!=2");
-//        check("delete from user where 1=1 and 2=2", "1=1 and 2=2");
+        checkEx("delete from user where 1=1 and 2=2", "1=1 and 2=2");
+        checkEx("delete from user where 1=1 and 2=3 or 1=1", "1=1 and 2=3 or 1=1");
     }
 
     void checkEx(String sql, String as) {