mirror of
https://github.com/alibaba/druid.git
synced 2023-03-04 19:17:16 +00:00
sql wall support
This commit is contained in:
@@ -14,19 +14,29 @@ import com.alibaba.druid.sql.parser.Token;
|
||||
public abstract class WallProvider {
|
||||
|
||||
// Dummy value to associate with an Object in the backing Map
|
||||
private static final Object PRESENT = new Object();
|
||||
private static final Object PRESENT = new Object();
|
||||
|
||||
private LinkedHashMap<String, Object> whiteList;
|
||||
|
||||
private int whileListMaxSize = 1024;
|
||||
private int whileListMaxSize = 1024;
|
||||
|
||||
private int whiteSqlMaxLength = 1024; // 1k
|
||||
private int whiteSqlMaxLength = 1024; // 1k
|
||||
|
||||
protected final Set<String> permitFunctions = new HashSet<String>();
|
||||
protected final Set<String> permitTables = new HashSet<String>();
|
||||
protected final Set<String> permitSchemas = new HashSet<String>();
|
||||
protected final Set<String> permitNames = new HashSet<String>();
|
||||
protected final Set<String> permitObjects = new HashSet<String>();
|
||||
protected final Set<String> permitFunctions = new HashSet<String>();
|
||||
protected final Set<String> permitTables = new HashSet<String>();
|
||||
protected final Set<String> permitSchemas = new HashSet<String>();
|
||||
protected final Set<String> permitNames = new HashSet<String>();
|
||||
protected final Set<String> permitObjects = new HashSet<String>();
|
||||
|
||||
private boolean checkSelectAlwayTrueCondition = true;
|
||||
|
||||
public boolean isCheckSelectAlwayTrueCondition() {
|
||||
return checkSelectAlwayTrueCondition;
|
||||
}
|
||||
|
||||
public void setCheckSelectAlwayTrueCondition(boolean checkSelectAlwayTrueCondition) {
|
||||
this.checkSelectAlwayTrueCondition = checkSelectAlwayTrueCondition;
|
||||
}
|
||||
|
||||
public synchronized void addWhiteSql(String sql) {
|
||||
if (whiteList == null) {
|
||||
|
||||
@@ -65,11 +65,17 @@ public class MySqlWallVisitor extends MySqlASTVisitorAdapter implements WallVisi
|
||||
|
||||
@Override
|
||||
public boolean visit(SQLSelectQueryBlock x) {
|
||||
WallVisitorUtils.checkCondition(this, x.getWhere());
|
||||
WallVisitorUtils.checkSelelctCondition(this, x.getWhere());
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean visit(MySqlSelectQueryBlock x) {
|
||||
WallVisitorUtils.checkSelelctCondition(this, x.getWhere());
|
||||
return true;
|
||||
}
|
||||
|
||||
public boolean visit(SQLSelectGroupByClause x) {
|
||||
WallVisitorUtils.checkCondition(this, x.getHaving());
|
||||
return true;
|
||||
@@ -80,12 +86,6 @@ public class MySqlWallVisitor extends MySqlASTVisitorAdapter implements WallVisi
|
||||
return true;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean visit(MySqlSelectQueryBlock x) {
|
||||
WallVisitorUtils.checkCondition(this, x.getWhere());
|
||||
return true;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean visit(MySqlDeleteStatement x) {
|
||||
WallVisitorUtils.checkCondition(this, x.getWhere());
|
||||
|
||||
@@ -99,14 +99,16 @@ public class OracleWallVisitor extends OracleASTVIsitorAdapter implements WallVi
|
||||
|
||||
@Override
|
||||
public boolean visit(SQLSelectQueryBlock x) {
|
||||
WallVisitorUtils.checkCondition(this, x.getWhere());
|
||||
WallVisitorUtils.checkSelelctCondition(this, x.getWhere());
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean visit(OracleSelectQueryBlock x) {
|
||||
return visit((SQLSelectQueryBlock) x);
|
||||
WallVisitorUtils.checkSelelctCondition(this, x.getWhere());
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
@Override
|
||||
|
||||
@@ -9,6 +9,7 @@ import java.util.Enumeration;
|
||||
import java.util.Set;
|
||||
|
||||
import com.alibaba.druid.filter.wall.IllegalSQLObjectViolation;
|
||||
import com.alibaba.druid.filter.wall.WallProvider;
|
||||
import com.alibaba.druid.filter.wall.WallVisitor;
|
||||
import com.alibaba.druid.logging.Log;
|
||||
import com.alibaba.druid.logging.LogFactory;
|
||||
@@ -21,6 +22,7 @@ import com.alibaba.druid.sql.ast.expr.SQLBinaryOpExpr;
|
||||
import com.alibaba.druid.sql.ast.expr.SQLBinaryOperator;
|
||||
import com.alibaba.druid.sql.ast.expr.SQLCharExpr;
|
||||
import com.alibaba.druid.sql.ast.expr.SQLIdentifierExpr;
|
||||
import com.alibaba.druid.sql.ast.expr.SQLIntegerExpr;
|
||||
import com.alibaba.druid.sql.ast.expr.SQLMethodInvokeExpr;
|
||||
import com.alibaba.druid.sql.ast.expr.SQLNCharExpr;
|
||||
import com.alibaba.druid.sql.ast.expr.SQLNotExpr;
|
||||
@@ -52,6 +54,30 @@ public class WallVisitorUtils {
|
||||
}
|
||||
}
|
||||
|
||||
public static void checkSelelctCondition(WallVisitor visitor, SQLExpr x) {
|
||||
if (x == null) {
|
||||
return;
|
||||
}
|
||||
|
||||
WallProvider provider = visitor.getWallProvider();
|
||||
if (!provider.isCheckSelectAlwayTrueCondition()) {
|
||||
return;
|
||||
}
|
||||
|
||||
if (Boolean.TRUE == getValue(x)) {
|
||||
if (x instanceof SQLBinaryOpExpr) {
|
||||
SQLBinaryOpExpr binaryOpExpr = (SQLBinaryOpExpr) x;
|
||||
if (binaryOpExpr.getOperator() == SQLBinaryOperator.Equality || binaryOpExpr.getOperator() == SQLBinaryOperator.NotEqual) {
|
||||
if (binaryOpExpr.getLeft() instanceof SQLIntegerExpr && binaryOpExpr.getRight() instanceof SQLIntegerExpr) {
|
||||
return;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
visitor.getViolations().add(new IllegalSQLObjectViolation(SQLUtils.toSQLString(x)));
|
||||
}
|
||||
}
|
||||
|
||||
public static void checkCondition(WallVisitor visitor, SQLExpr x) {
|
||||
if (x == null) {
|
||||
return;
|
||||
|
||||
@@ -15,10 +15,10 @@ public class WallSelectWhereTest extends TestCase {
|
||||
private String sql = "SELECT F1, F2 WHERE 1 = 1";
|
||||
|
||||
public void testMySql() throws Exception {
|
||||
Assert.assertFalse(WallUtils.isValidateMySql(sql));
|
||||
Assert.assertTrue(WallUtils.isValidateMySql(sql));
|
||||
}
|
||||
|
||||
public void testORACLE() throws Exception {
|
||||
Assert.assertFalse(WallUtils.isValidateOracle(sql));
|
||||
Assert.assertTrue(WallUtils.isValidateOracle(sql));
|
||||
}
|
||||
}
|
||||
|
||||
@@ -0,0 +1,24 @@
|
||||
package com.alibaba.druid.bvt.filter.wall;
|
||||
|
||||
import junit.framework.TestCase;
|
||||
|
||||
import org.junit.Assert;
|
||||
|
||||
import com.alibaba.druid.filter.wall.WallUtils;
|
||||
|
||||
/**
|
||||
* 这个场景,检测可疑的Having条件
|
||||
* @author wenshao
|
||||
*
|
||||
*/
|
||||
public class WallSelectWhereTest0 extends TestCase {
|
||||
private String sql = "SELECT F1, F2 WHERE 1 = 1 OR F1 = ?";
|
||||
|
||||
public void testMySql() throws Exception {
|
||||
Assert.assertFalse(WallUtils.isValidateMySql(sql));
|
||||
}
|
||||
|
||||
public void testORACLE() throws Exception {
|
||||
Assert.assertFalse(WallUtils.isValidateOracle(sql));
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user