sql wall support

This commit is contained in:
温少
2012-03-16 22:14:39 +08:00
6 changed files with 81 additions and 19 deletions
@@ -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));
}
}