diff --git a/src/main/java/com/alibaba/druid/sql/visitor/SQLEvalVisitorUtils.java b/src/main/java/com/alibaba/druid/sql/visitor/SQLEvalVisitorUtils.java index 0656de218c..10e5359333 100644 --- a/src/main/java/com/alibaba/druid/sql/visitor/SQLEvalVisitorUtils.java +++ b/src/main/java/com/alibaba/druid/sql/visitor/SQLEvalVisitorUtils.java @@ -854,6 +854,12 @@ public class SQLEvalVisitorUtils { wallConditionContext.setPartAlwayTrue(true); } } + } else if (x.getOperator() == SQLBinaryOperator.BooleanAnd) { + if (wallConditionContext != null) { + if (left.getAttribute(EVAL_VALUE) == Boolean.FALSE || right.getAttribute(EVAL_VALUE) == Boolean.FALSE) { + wallConditionContext.setPartAlwayFalse(true); + } + } } else if (x.getOperator() == SQLBinaryOperator.BooleanXor) { if (wallConditionContext != null) { wallConditionContext.setXor(true); diff --git a/src/main/java/com/alibaba/druid/wall/WallConfig.java b/src/main/java/com/alibaba/druid/wall/WallConfig.java index cc6ec4d723..61d05f39b4 100644 --- a/src/main/java/com/alibaba/druid/wall/WallConfig.java +++ b/src/main/java/com/alibaba/druid/wall/WallConfig.java @@ -24,80 +24,81 @@ import com.alibaba.druid.wall.spi.WallVisitorUtils; public class WallConfig implements WallConfigMBean { - private boolean noneBaseStatementAllow = false; + private boolean noneBaseStatementAllow = false; - private boolean callAllow = true; - private boolean selelctAllow = true; - private boolean selectIntoAllow = true; - private boolean selectIntoOutfileAllow = false; - private boolean selectWhereAlwayTrueCheck = true; - private boolean selectHavingAlwayTrueCheck = true; - private boolean selectUnionCheck = true; - private boolean selectMinusCheck = true; - private boolean selectExceptCheck = true; - private boolean selectIntersectCheck = true; - private boolean createTableAllow = true; - private boolean dropTableAllow = true; - private boolean alterTableAllow = true; + private boolean callAllow = true; + private boolean selelctAllow = true; + private boolean selectIntoAllow = true; + private boolean selectIntoOutfileAllow = false; + private boolean selectWhereAlwayTrueCheck = true; + private boolean selectHavingAlwayTrueCheck = true; + private boolean selectUnionCheck = true; + private boolean selectMinusCheck = true; + private boolean selectExceptCheck = true; + private boolean selectIntersectCheck = true; + private boolean createTableAllow = true; + private boolean dropTableAllow = true; + private boolean alterTableAllow = true; - private boolean conditionAndAlwayTrueAllow = false; - private boolean conditionDoubleConstAllow = false; - private boolean conditionLikeTrueAllow = true; + private boolean conditionAndAlwayTrueAllow = false; + private boolean conditionAndAlwayFalseAllow = false; + private boolean conditionDoubleConstAllow = false; + private boolean conditionLikeTrueAllow = true; - private boolean selectAllColumnAllow = true; + private boolean selectAllColumnAllow = true; - private boolean deleteAllow = true; - private boolean deleteWhereAlwayTrueCheck = true; - private boolean deleteWhereNoneCheck = false; + private boolean deleteAllow = true; + private boolean deleteWhereAlwayTrueCheck = true; + private boolean deleteWhereNoneCheck = false; - private boolean updateAllow = true; - private boolean updateWhereAlayTrueCheck = true; - private boolean updateWhereNoneCheck = false; + private boolean updateAllow = true; + private boolean updateWhereAlayTrueCheck = true; + private boolean updateWhereNoneCheck = false; - private boolean insertAllow = true; - private boolean mergeAllow = true; - private boolean minusAllow = true; - private boolean intersectAllow = true; - private boolean replaceAllow = true; - private boolean setAllow = true; - private boolean commitAllow = true; - private boolean rollbackAllow = true; - private boolean useAllow = true; + private boolean insertAllow = true; + private boolean mergeAllow = true; + private boolean minusAllow = true; + private boolean intersectAllow = true; + private boolean replaceAllow = true; + private boolean setAllow = true; + private boolean commitAllow = true; + private boolean rollbackAllow = true; + private boolean useAllow = true; - private boolean multiStatementAllow = false; + private boolean multiStatementAllow = false; - private boolean truncateAllow = true; + private boolean truncateAllow = true; - private boolean commentAllow = false; - private boolean strictSyntaxCheck = true; - private boolean constArithmeticAllow = true; - private boolean limitZeroAllow = false; + private boolean commentAllow = false; + private boolean strictSyntaxCheck = true; + private boolean constArithmeticAllow = true; + private boolean limitZeroAllow = false; - private boolean describeAllow = true; - private boolean showAllow = true; + private boolean describeAllow = true; + private boolean showAllow = true; - private boolean schemaCheck = true; - private boolean tableCheck = true; - private boolean functionCheck = true; - private boolean objectCheck = true; - private boolean variantCheck = true; + private boolean schemaCheck = true; + private boolean tableCheck = true; + private boolean functionCheck = true; + private boolean objectCheck = true; + private boolean variantCheck = true; - private boolean mustParameterized = false; + private boolean mustParameterized = false; - private boolean doPrivilegedAllow = false; + private boolean doPrivilegedAllow = false; - protected final Set denyFunctions = new ConcurrentSkipListSet(); - protected final Set denyTables = new ConcurrentSkipListSet(); - protected final Set denySchemas = new ConcurrentSkipListSet(); - protected final Set denyVariants = new ConcurrentSkipListSet(); - protected final Set denyObjects = new ConcurrentSkipListSet(); + protected final Set denyFunctions = new ConcurrentSkipListSet(); + protected final Set denyTables = new ConcurrentSkipListSet(); + protected final Set denySchemas = new ConcurrentSkipListSet(); + protected final Set denyVariants = new ConcurrentSkipListSet(); + protected final Set denyObjects = new ConcurrentSkipListSet(); - protected final Set permitFunctions = new ConcurrentSkipListSet(); - protected final Set permitTables = new ConcurrentSkipListSet(); - protected final Set permitSchemas = new ConcurrentSkipListSet(); - protected final Set permitVariants = new ConcurrentSkipListSet(); + protected final Set permitFunctions = new ConcurrentSkipListSet(); + protected final Set permitTables = new ConcurrentSkipListSet(); + protected final Set permitSchemas = new ConcurrentSkipListSet(); + protected final Set permitVariants = new ConcurrentSkipListSet(); - protected final Set readOnlyTables = new ConcurrentSkipListSet(); + protected final Set readOnlyTables = new ConcurrentSkipListSet(); private String dir; @@ -106,13 +107,13 @@ public class WallConfig implements WallConfigMBean { private String tenantTablePattern; private String tenantColumn; - private boolean wrapAllow = true; - private boolean metadataAllow = true; + private boolean wrapAllow = true; + private boolean metadataAllow = true; - private boolean conditionOpXorAllow = false; - private boolean conditionOpBitwseAllow = true; + private boolean conditionOpXorAllow = false; + private boolean conditionOpBitwseAllow = true; - private boolean caseConditionAllow = false; + private boolean caseConditionAllow = false; public WallConfig(){ @@ -158,6 +159,14 @@ public class WallConfig implements WallConfigMBean { this.conditionAndAlwayTrueAllow = conditionAndAlwayTrueAllow; } + public boolean isConditionAndAlwayFalseAllow() { + return conditionAndAlwayFalseAllow; + } + + public void setConditionAndAlwayFalseAllow(boolean conditionAndAlwayFalseAllow) { + this.conditionAndAlwayFalseAllow = conditionAndAlwayFalseAllow; + } + public boolean isUseAllow() { return useAllow; } diff --git a/src/main/java/com/alibaba/druid/wall/spi/WallVisitorUtils.java b/src/main/java/com/alibaba/druid/wall/spi/WallVisitorUtils.java index b829e8013d..370da33580 100644 --- a/src/main/java/com/alibaba/druid/wall/spi/WallVisitorUtils.java +++ b/src/main/java/com/alibaba/druid/wall/spi/WallVisitorUtils.java @@ -33,7 +33,6 @@ import com.alibaba.druid.sql.ast.SQLExpr; import com.alibaba.druid.sql.ast.SQLName; import com.alibaba.druid.sql.ast.SQLObject; import com.alibaba.druid.sql.ast.SQLStatement; -import com.alibaba.druid.sql.ast.SQLStatementImpl; import com.alibaba.druid.sql.ast.expr.SQLAggregateExpr; import com.alibaba.druid.sql.ast.expr.SQLAllColumnExpr; import com.alibaba.druid.sql.ast.expr.SQLBetweenExpr; @@ -650,6 +649,10 @@ public class WallVisitorUtils { } dalConst++; } else if (Boolean.FALSE == booleanVal) { + final WallConditionContext wallContext = WallVisitorUtils.getWallConditionContext(); + if (wallContext != null && !isFirst(item)) { + wallContext.setPartAlwayFalse(true); + } allTrue = Boolean.FALSE; dalConst++; } else { @@ -869,17 +872,26 @@ public class WallVisitorUtils { public static class WallConditionContext { - private boolean partAlwayrue; + private boolean partAlwayTrue = false; + private boolean partAlwayFalse = false; private boolean constArithmetic = false; private boolean xor = false; private boolean bitwise = false; public boolean hasPartAlwayTrue() { - return partAlwayrue; + return partAlwayTrue; } public void setPartAlwayTrue(boolean partAllowTrue) { - this.partAlwayrue = partAllowTrue; + this.partAlwayTrue = partAllowTrue; + } + + public boolean hasPartAlwayFalse() { + return partAlwayFalse; + } + + public void setPartAlwayFalse(boolean partAlwayFalse) { + this.partAlwayFalse = partAlwayFalse; } public boolean hasConstArithmetic() { @@ -947,6 +959,10 @@ public class WallVisitorUtils { addViolation(visitor, ErrorCode.ALWAY_TRUE, "part alway true condition not allow", x); } + if (current.hasPartAlwayFalse() && !visitor.getConfig().isConditionAndAlwayFalseAllow()) { + addViolation(visitor, ErrorCode.ALWAY_FALSE, "part alway false condition not allow", x); + } + if (current.hasConstArithmetic() && !visitor.getConfig().isConstArithmeticAllow()) { addViolation(visitor, ErrorCode.CONST_ARITHMETIC, "const arithmetic not allow", x); } @@ -1548,7 +1564,7 @@ public class WallVisitorUtils { if (x instanceof SQLExprTableSource) { x = x.getParent(); - if (x instanceof SQLStatementImpl) { + if (x instanceof SQLStatement) { x = x.getParent(); if (x == null) { return true; diff --git a/src/main/java/com/alibaba/druid/wall/violation/ErrorCode.java b/src/main/java/com/alibaba/druid/wall/violation/ErrorCode.java index 0159fc69db..eeb9add391 100644 --- a/src/main/java/com/alibaba/druid/wall/violation/ErrorCode.java +++ b/src/main/java/com/alibaba/druid/wall/violation/ErrorCode.java @@ -67,6 +67,7 @@ public interface ErrorCode { public final static int EVIL_HINTS = 2110; public final static int EVIL_NAME = 2111; public final static int EVIL_CONCAT = 2112; + public final static int ALWAY_FALSE = 2113; public final static int NOT_PARAMETERIZED = 2200; public final static int MULTI_TENANT = 2201;