mirror of
https://github.com/alibaba/druid.git
synced 2023-03-04 19:17:16 +00:00
improve WallFilter, support conditionOpBitwiseAllow
This commit is contained in:
@@ -38,7 +38,6 @@ public enum SQLBinaryOperator {
|
||||
|
||||
BitwiseAnd("&", 90),
|
||||
BitwiseOr("|", 100),
|
||||
InvertBits("~", 100),
|
||||
|
||||
GreaterThan(">", 110),
|
||||
GreaterThanOrEqual(">=", 110),
|
||||
|
||||
@@ -28,6 +28,7 @@ import com.alibaba.druid.sql.ast.expr.SQLMethodInvokeExpr;
|
||||
import com.alibaba.druid.sql.ast.expr.SQLNullExpr;
|
||||
import com.alibaba.druid.sql.ast.expr.SQLNumberExpr;
|
||||
import com.alibaba.druid.sql.ast.expr.SQLQueryExpr;
|
||||
import com.alibaba.druid.sql.ast.expr.SQLUnaryExpr;
|
||||
import com.alibaba.druid.sql.ast.expr.SQLVariantRefExpr;
|
||||
import com.alibaba.druid.sql.dialect.mysql.ast.expr.MySqlBooleanExpr;
|
||||
import com.alibaba.druid.sql.visitor.SQLEvalVisitor;
|
||||
@@ -76,6 +77,10 @@ public class MySqlEvalVisitorImpl extends MySqlASTVisitorAdapter implements SQLE
|
||||
public boolean visit(SQLBinaryOpExpr x) {
|
||||
return SQLEvalVisitorUtils.visit(this, x);
|
||||
}
|
||||
|
||||
public boolean visit(SQLUnaryExpr x) {
|
||||
return SQLEvalVisitorUtils.visit(this, x);
|
||||
}
|
||||
|
||||
public boolean visit(SQLIntegerExpr x) {
|
||||
return SQLEvalVisitorUtils.visit(this, x);
|
||||
|
||||
@@ -27,6 +27,7 @@ import com.alibaba.druid.sql.ast.expr.SQLMethodInvokeExpr;
|
||||
import com.alibaba.druid.sql.ast.expr.SQLNullExpr;
|
||||
import com.alibaba.druid.sql.ast.expr.SQLNumberExpr;
|
||||
import com.alibaba.druid.sql.ast.expr.SQLQueryExpr;
|
||||
import com.alibaba.druid.sql.ast.expr.SQLUnaryExpr;
|
||||
import com.alibaba.druid.sql.ast.expr.SQLVariantRefExpr;
|
||||
import com.alibaba.druid.sql.visitor.SQLEvalVisitor;
|
||||
import com.alibaba.druid.sql.visitor.SQLEvalVisitorUtils;
|
||||
@@ -74,6 +75,10 @@ public class OracleEvalVisitor extends OracleASTVisitorAdapter implements SQLEva
|
||||
public boolean visit(SQLBinaryOpExpr x) {
|
||||
return SQLEvalVisitorUtils.visit(this, x);
|
||||
}
|
||||
|
||||
public boolean visit(SQLUnaryExpr x) {
|
||||
return SQLEvalVisitorUtils.visit(this, x);
|
||||
}
|
||||
|
||||
public boolean visit(SQLIntegerExpr x) {
|
||||
return SQLEvalVisitorUtils.visit(this, x);
|
||||
|
||||
@@ -27,6 +27,7 @@ import com.alibaba.druid.sql.ast.expr.SQLMethodInvokeExpr;
|
||||
import com.alibaba.druid.sql.ast.expr.SQLNullExpr;
|
||||
import com.alibaba.druid.sql.ast.expr.SQLNumberExpr;
|
||||
import com.alibaba.druid.sql.ast.expr.SQLQueryExpr;
|
||||
import com.alibaba.druid.sql.ast.expr.SQLUnaryExpr;
|
||||
import com.alibaba.druid.sql.ast.expr.SQLVariantRefExpr;
|
||||
import com.alibaba.druid.sql.visitor.SQLEvalVisitor;
|
||||
import com.alibaba.druid.sql.visitor.SQLEvalVisitorUtils;
|
||||
@@ -74,6 +75,10 @@ public class PGEvalVisitor extends PGASTVisitorAdapter implements SQLEvalVisitor
|
||||
public boolean visit(SQLBinaryOpExpr x) {
|
||||
return SQLEvalVisitorUtils.visit(this, x);
|
||||
}
|
||||
|
||||
public boolean visit(SQLUnaryExpr x) {
|
||||
return SQLEvalVisitorUtils.visit(this, x);
|
||||
}
|
||||
|
||||
public boolean visit(SQLIntegerExpr x) {
|
||||
return SQLEvalVisitorUtils.visit(this, x);
|
||||
|
||||
+5
@@ -27,6 +27,7 @@ import com.alibaba.druid.sql.ast.expr.SQLMethodInvokeExpr;
|
||||
import com.alibaba.druid.sql.ast.expr.SQLNullExpr;
|
||||
import com.alibaba.druid.sql.ast.expr.SQLNumberExpr;
|
||||
import com.alibaba.druid.sql.ast.expr.SQLQueryExpr;
|
||||
import com.alibaba.druid.sql.ast.expr.SQLUnaryExpr;
|
||||
import com.alibaba.druid.sql.ast.expr.SQLVariantRefExpr;
|
||||
import com.alibaba.druid.sql.visitor.SQLEvalVisitor;
|
||||
import com.alibaba.druid.sql.visitor.SQLEvalVisitorUtils;
|
||||
@@ -74,6 +75,10 @@ public class SQLServerEvalVisitor extends SQLServerASTVisitorAdapter implements
|
||||
public boolean visit(SQLBinaryOpExpr x) {
|
||||
return SQLEvalVisitorUtils.visit(this, x);
|
||||
}
|
||||
|
||||
public boolean visit(SQLUnaryExpr x) {
|
||||
return SQLEvalVisitorUtils.visit(this, x);
|
||||
}
|
||||
|
||||
public boolean visit(SQLIntegerExpr x) {
|
||||
return SQLEvalVisitorUtils.visit(this, x);
|
||||
|
||||
@@ -126,7 +126,7 @@ public class SQLExprParser extends SQLParser {
|
||||
}
|
||||
|
||||
public final SQLExpr multiplicative() {
|
||||
SQLExpr expr = primary();
|
||||
SQLExpr expr = bitXor();
|
||||
return multiplicativeRest(expr);
|
||||
}
|
||||
|
||||
@@ -798,17 +798,12 @@ public class SQLExprParser extends SQLParser {
|
||||
SQLExpr rightExp = bitAnd();
|
||||
expr = new SQLBinaryOpExpr(expr, SQLBinaryOperator.BitwiseOr, rightExp);
|
||||
expr = bitAndRest(expr);
|
||||
} else if (lexer.token() == Token.TILDE) {
|
||||
lexer.nextToken();
|
||||
SQLExpr rightExp = bitAnd();
|
||||
expr = new SQLBinaryOpExpr(expr, SQLBinaryOperator.InvertBits, rightExp);
|
||||
expr = bitAndRest(expr);
|
||||
}
|
||||
return expr;
|
||||
}
|
||||
|
||||
public final SQLExpr equality() {
|
||||
SQLExpr expr = shift();
|
||||
SQLExpr expr = bitOr();
|
||||
return equalityRest(expr);
|
||||
}
|
||||
|
||||
@@ -816,14 +811,14 @@ public class SQLExprParser extends SQLParser {
|
||||
SQLExpr rightExp;
|
||||
if (lexer.token() == Token.EQ) {
|
||||
lexer.nextToken();
|
||||
rightExp = shift();
|
||||
rightExp = bitOr();
|
||||
|
||||
rightExp = equalityRest(rightExp);
|
||||
|
||||
expr = new SQLBinaryOpExpr(expr, SQLBinaryOperator.Equality, rightExp);
|
||||
} else if (lexer.token() == Token.BANGEQ) {
|
||||
lexer.nextToken();
|
||||
rightExp = shift();
|
||||
rightExp = bitOr();
|
||||
|
||||
rightExp = equalityRest(rightExp);
|
||||
|
||||
|
||||
@@ -43,6 +43,8 @@ import com.alibaba.druid.sql.ast.expr.SQLMethodInvokeExpr;
|
||||
import com.alibaba.druid.sql.ast.expr.SQLNullExpr;
|
||||
import com.alibaba.druid.sql.ast.expr.SQLNumericLiteralExpr;
|
||||
import com.alibaba.druid.sql.ast.expr.SQLQueryExpr;
|
||||
import com.alibaba.druid.sql.ast.expr.SQLUnaryExpr;
|
||||
import com.alibaba.druid.sql.ast.expr.SQLUnaryOperator;
|
||||
import com.alibaba.druid.sql.ast.expr.SQLVariantRefExpr;
|
||||
import com.alibaba.druid.sql.ast.statement.SQLExprTableSource;
|
||||
import com.alibaba.druid.sql.ast.statement.SQLSelectItem;
|
||||
@@ -114,17 +116,17 @@ public class SQLEvalVisitorUtils {
|
||||
if (JdbcUtils.POSTGRESQL.equals(dbType)) {
|
||||
return new PGEvalVisitor();
|
||||
}
|
||||
|
||||
|
||||
if (JdbcUtils.SQL_SERVER.equals(dbType)) {
|
||||
return new SQLServerEvalVisitor();
|
||||
}
|
||||
|
||||
return new SQLEvalVisitorImpl();
|
||||
}
|
||||
|
||||
|
||||
public static boolean visit(SQLEvalVisitor visitor, SQLMethodInvokeExpr x) {
|
||||
String methodName = x.getMethodName().toLowerCase();
|
||||
|
||||
|
||||
if ("concat".equals(methodName)) {
|
||||
StringBuilder buf = new StringBuilder();
|
||||
|
||||
@@ -762,7 +764,7 @@ public class SQLEvalVisitorUtils {
|
||||
x.putAttribute(EVAL_VALUE, 1);
|
||||
return false;
|
||||
}
|
||||
|
||||
|
||||
if (x.getSubQuery().getQuery() instanceof SQLSelectQueryBlock) {
|
||||
SQLSelectQueryBlock queryBlock = (SQLSelectQueryBlock) x.getSubQuery().getQuery();
|
||||
|
||||
@@ -801,6 +803,15 @@ public class SQLEvalVisitorUtils {
|
||||
return false;
|
||||
}
|
||||
|
||||
public static boolean visit(SQLEvalVisitor visitor, SQLUnaryExpr x) {
|
||||
final WallConditionContext wallConditionContext = WallVisitorUtils.getWallConditionContext();
|
||||
if (x.getOperator() == SQLUnaryOperator.Compl && wallConditionContext != null) {
|
||||
wallConditionContext.setBitwise(true);
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
public static boolean visit(SQLEvalVisitor visitor, SQLBinaryOpExpr x) {
|
||||
SQLExpr left = x.getLeft();
|
||||
SQLExpr right = x.getRight();
|
||||
@@ -817,25 +828,36 @@ public class SQLEvalVisitorUtils {
|
||||
wallConditionContext.setPartAlwayTrue(true);
|
||||
}
|
||||
}
|
||||
} else if (x.getOperator() == SQLBinaryOperator.BooleanXor) {
|
||||
if (wallConditionContext != null) {
|
||||
wallConditionContext.setXor(true);
|
||||
}
|
||||
} else if (x.getOperator() == SQLBinaryOperator.BitwiseAnd //
|
||||
|| x.getOperator() == SQLBinaryOperator.BitwiseNot //
|
||||
|| x.getOperator() == SQLBinaryOperator.BitwiseOr //
|
||||
|| x.getOperator() == SQLBinaryOperator.BitwiseXor) {
|
||||
if (wallConditionContext != null) {
|
||||
wallConditionContext.setBitwise(true);
|
||||
}
|
||||
}
|
||||
|
||||
Object leftValue = left.getAttribute(EVAL_VALUE);
|
||||
Object rightValue = right.getAttributes().get(EVAL_VALUE);
|
||||
|
||||
|
||||
if (x.getOperator() == SQLBinaryOperator.Like) {
|
||||
if (isAlwayTrueLikePattern(x.getRight())) {
|
||||
x.putAttribute(EVAL_VALUE, Boolean.TRUE);
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
if (x.getOperator() == SQLBinaryOperator.NotLike) {
|
||||
if (isAlwayTrueLikePattern(x)) {
|
||||
x.putAttribute(EVAL_VALUE, Boolean.FALSE);
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
if (!left.getAttributes().containsKey(EVAL_VALUE)) {
|
||||
return false;
|
||||
}
|
||||
@@ -845,17 +867,7 @@ public class SQLEvalVisitorUtils {
|
||||
}
|
||||
|
||||
if (wallConditionContext != null) {
|
||||
switch (x.getOperator()) {
|
||||
case Add:
|
||||
case Subtract:
|
||||
case Multiply:
|
||||
case Divide:
|
||||
case Modulus:
|
||||
wallConditionContext.setConstArithmetic(true);
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
wallConditionContext.setConstArithmetic(true);
|
||||
}
|
||||
|
||||
Object value = null;
|
||||
@@ -911,30 +923,30 @@ public class SQLEvalVisitorUtils {
|
||||
String input = castToString(left.getAttributes().get(EVAL_VALUE));
|
||||
boolean matchResult = Pattern.matches(pattern, input);
|
||||
x.putAttribute(EVAL_VALUE, matchResult);
|
||||
}
|
||||
break;
|
||||
}
|
||||
case NotRegExp:
|
||||
case NotRLike: {
|
||||
String pattern = castToString(rightValue);
|
||||
String input = castToString(left.getAttributes().get(EVAL_VALUE));
|
||||
boolean matchResult = !Pattern.matches(pattern, input);
|
||||
x.putAttribute(EVAL_VALUE, matchResult);
|
||||
}
|
||||
break;
|
||||
}
|
||||
case Like: {
|
||||
String pattern = castToString(rightValue);
|
||||
String input = castToString(left.getAttributes().get(EVAL_VALUE));
|
||||
boolean matchResult = like(input, pattern);
|
||||
x.putAttribute(EVAL_VALUE, matchResult);
|
||||
}
|
||||
break;
|
||||
}
|
||||
case NotLike: {
|
||||
String pattern = castToString(rightValue);
|
||||
String input = castToString(left.getAttributes().get(EVAL_VALUE));
|
||||
boolean matchResult = !like(input, pattern);
|
||||
x.putAttribute(EVAL_VALUE, matchResult);
|
||||
}
|
||||
break;
|
||||
}
|
||||
case Concat: {
|
||||
String result = leftValue.toString() + rightValue.toString();
|
||||
x.putAttribute(EVAL_VALUE, result);
|
||||
@@ -1609,6 +1621,5 @@ public class SQLEvalVisitorUtils {
|
||||
String regexpr = regexprBuilder.toString();
|
||||
return Pattern.matches(regexpr, input);
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
|
||||
@@ -51,7 +51,7 @@ public class WallConfig implements WallConfigMBean {
|
||||
|
||||
private boolean commentAllow = false;
|
||||
private boolean strictSyntaxCheck = true;
|
||||
private boolean constArithmeticAllow = false;
|
||||
private boolean constArithmeticAllow = true;
|
||||
|
||||
private boolean describeAllow = false;
|
||||
|
||||
@@ -83,10 +83,29 @@ public class WallConfig implements WallConfigMBean {
|
||||
private boolean wrapAllow = true;
|
||||
private boolean metadataAllow = true;
|
||||
|
||||
private boolean conditionOpXorAllow = false;
|
||||
private boolean conditionOpBitwseAllow = false;
|
||||
|
||||
public WallConfig(){
|
||||
|
||||
}
|
||||
|
||||
public boolean isConditionOpXorAllow() {
|
||||
return conditionOpXorAllow;
|
||||
}
|
||||
|
||||
public void setConditionOpXorAllow(boolean conditionOpXorAllow) {
|
||||
this.conditionOpXorAllow = conditionOpXorAllow;
|
||||
}
|
||||
|
||||
public boolean isConditionOpBitwseAllow() {
|
||||
return conditionOpBitwseAllow;
|
||||
}
|
||||
|
||||
public void setConditionOpBitwseAllow(boolean conditionOpBitwseAllow) {
|
||||
this.conditionOpBitwseAllow = conditionOpBitwseAllow;
|
||||
}
|
||||
|
||||
public String getTenantTablePattern() {
|
||||
return tenantTablePattern;
|
||||
}
|
||||
|
||||
@@ -464,24 +464,26 @@ public class WallVisitorUtils {
|
||||
if (wallContext != null) {
|
||||
dbType = wallContext.getDbType();
|
||||
}
|
||||
|
||||
|
||||
return SQLEvalVisitorUtils.eval(dbType, x, Collections.emptyList(), false);
|
||||
}
|
||||
|
||||
public static class WallConditionContext {
|
||||
|
||||
private boolean partAllowTrue;
|
||||
private boolean partAlwayrue;
|
||||
private boolean constArithmetic = false;
|
||||
private boolean xor = false;
|
||||
private boolean bitwise = false;
|
||||
|
||||
public boolean isPartAllowTrue() {
|
||||
return partAllowTrue;
|
||||
public boolean hasPartAlwayTrue() {
|
||||
return partAlwayrue;
|
||||
}
|
||||
|
||||
public void setPartAlwayTrue(boolean partAllowTrue) {
|
||||
this.partAllowTrue = partAllowTrue;
|
||||
this.partAlwayrue = partAllowTrue;
|
||||
}
|
||||
|
||||
public boolean isConstArithmetic() {
|
||||
public boolean hasConstArithmetic() {
|
||||
return constArithmetic;
|
||||
}
|
||||
|
||||
@@ -489,6 +491,21 @@ public class WallVisitorUtils {
|
||||
this.constArithmetic = constArithmetic;
|
||||
}
|
||||
|
||||
public boolean hasXor() {
|
||||
return xor;
|
||||
}
|
||||
|
||||
public void setXor(boolean xor) {
|
||||
this.xor = xor;
|
||||
}
|
||||
|
||||
public boolean hasBitwise() {
|
||||
return bitwise;
|
||||
}
|
||||
|
||||
public void setBitwise(boolean bitwise) {
|
||||
this.bitwise = bitwise;
|
||||
}
|
||||
}
|
||||
|
||||
private static ThreadLocal<WallConditionContext> wallConditionContextLocal = new ThreadLocal<WallConditionContext>();
|
||||
@@ -504,11 +521,19 @@ public class WallVisitorUtils {
|
||||
final Object value = getValue(x);
|
||||
|
||||
final WallConditionContext current = wallConditionContextLocal.get();
|
||||
if (current.isPartAllowTrue() && alwayTrueCheck) {
|
||||
if (current.hasPartAlwayTrue() && alwayTrueCheck) {
|
||||
addViolation(visitor, x);
|
||||
}
|
||||
|
||||
if (current.isConstArithmetic() && !visitor.getConfig().isConstArithmeticAllow()) {
|
||||
if (current.hasConstArithmetic() && !visitor.getConfig().isConstArithmeticAllow()) {
|
||||
addViolation(visitor, x);
|
||||
}
|
||||
|
||||
if (current.hasXor() && !visitor.getConfig().isConditionOpXorAllow()) {
|
||||
addViolation(visitor, x);
|
||||
}
|
||||
|
||||
if (current.hasBitwise() && !visitor.getConfig().isConditionOpBitwseAllow()) {
|
||||
addViolation(visitor, x);
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user