improve wall filter

This commit is contained in:
wenshao
2013-04-08 12:54:16 +08:00
parent de60312713
commit 866ddaaaed
12 changed files with 112 additions and 10 deletions
@@ -19,6 +19,7 @@ import java.lang.management.ManagementFactory;
import java.sql.Driver;
import java.sql.DriverManager;
import java.util.ArrayList;
import java.util.Collection;
import java.util.Date;
import java.util.Enumeration;
import java.util.HashMap;
@@ -208,6 +209,25 @@ public final class DruidStatManagerFacade {
newMap.put(key, valueB);
} else if (valueB == null) {
newMap.put(key, valueA);
} else if ("blackList".equals(key)) {
Set<String> newSet = new HashSet<String>();
Collection<String> collectionA = (Collection<String>) valueA;
for (String blackItem : collectionA) {
if (newSet.size() >= 500) {
break;
}
newSet.add(blackItem);
}
Collection<String> collectionB = (Collection<String>) valueB;
for (String blackItem : collectionB) {
if (newSet.size() >= 50) {
break;
}
newSet.add(blackItem);
}
newMap.put(key, newSet);
} else {
if (valueA instanceof Map && valueB instanceof Map) {
Object newValue = mergWallStat((Map)valueA, (Map)valueB);
@@ -267,6 +267,7 @@ public final class DruidStatService implements DruidStatServiceMBean {
return sortedArray;
}
@SuppressWarnings("unchecked")
public Map<String, Object> getWallStatMap(Map<String, String> parameters) {
Integer dataSourceId = null;
@@ -53,6 +53,8 @@ public class WallConfig implements WallConfigMBean {
private boolean intersectAllow = false;
private boolean replaceAllow = true;
private boolean setAllow = true;
private boolean commitAllow = true;
private boolean useAllow = false;
private boolean multiStatementAllow = false;
@@ -104,6 +106,23 @@ public class WallConfig implements WallConfigMBean {
public WallConfig(){
}
public boolean isUseAllow() {
return useAllow;
}
public void setUseAllow(boolean useAllow) {
this.useAllow = useAllow;
}
public boolean isCommitAllow() {
return commitAllow;
}
public void setCommitAllow(boolean commitAllow) {
this.commitAllow = commitAllow;
}
public boolean isIntersectAllow() {
return intersectAllow;
@@ -46,11 +46,11 @@ public abstract class WallProvider {
private int MAX_SQL_LENGTH = 2048; // 1k
private int whiteSqlMaxSize = 500; // 1k
private int whiteSqlMaxSize = 500; // 1k
private LRUCache<String, WallSqlStat> blackList;
private int blackSqlMaxSize = 500; // 1k
private int blackSqlMaxSize = 100; // 1k
protected final WallConfig config;
@@ -635,8 +635,8 @@ public abstract class WallProvider {
}
info.put("functions", functions);
}
//info.put("whiteList", this.getWhiteList());
//info.put("blackList", this.getBlackList());
// info.put("whiteList", this.getWhiteList());
info.put("blackList", this.getBlackList());
return info;
}
}
@@ -29,6 +29,7 @@ import com.alibaba.druid.sql.ast.expr.SQLPropertyExpr;
import com.alibaba.druid.sql.ast.expr.SQLVariantRefExpr;
import com.alibaba.druid.sql.ast.statement.SQLAlterTableStatement;
import com.alibaba.druid.sql.ast.statement.SQLAssignItem;
import com.alibaba.druid.sql.ast.statement.SQLCallStatement;
import com.alibaba.druid.sql.ast.statement.SQLCreateTableStatement;
import com.alibaba.druid.sql.ast.statement.SQLDeleteStatement;
import com.alibaba.druid.sql.ast.statement.SQLDropTableStatement;
@@ -348,4 +349,9 @@ public class MySqlWallVisitor extends MySqlASTVisitorAdapter implements WallVisi
public boolean visit(MySqlReplaceStatement x) {
return true;
}
@Override
public boolean visit(SQLCallStatement x) {
return false;
}
}
@@ -27,6 +27,7 @@ import com.alibaba.druid.sql.ast.expr.SQLInListExpr;
import com.alibaba.druid.sql.ast.expr.SQLMethodInvokeExpr;
import com.alibaba.druid.sql.ast.expr.SQLPropertyExpr;
import com.alibaba.druid.sql.ast.statement.SQLAlterTableStatement;
import com.alibaba.druid.sql.ast.statement.SQLCallStatement;
import com.alibaba.druid.sql.ast.statement.SQLCreateTableStatement;
import com.alibaba.druid.sql.ast.statement.SQLDeleteStatement;
import com.alibaba.druid.sql.ast.statement.SQLDropTableStatement;
@@ -39,6 +40,7 @@ import com.alibaba.druid.sql.ast.statement.SQLSelectStatement;
import com.alibaba.druid.sql.ast.statement.SQLSetStatement;
import com.alibaba.druid.sql.ast.statement.SQLUnionQuery;
import com.alibaba.druid.sql.ast.statement.SQLUpdateStatement;
import com.alibaba.druid.sql.dialect.mysql.ast.statement.MySqlReplaceStatement;
import com.alibaba.druid.sql.dialect.oracle.ast.stmt.OracleAlterTableStatement;
import com.alibaba.druid.sql.dialect.oracle.ast.stmt.OracleCreateTableStatement;
import com.alibaba.druid.sql.dialect.oracle.ast.stmt.OracleDeleteStatement;
@@ -277,4 +279,13 @@ public class OracleWallVisitor extends OracleASTVisitorAdapter implements WallVi
public boolean visit(SQLSetStatement x) {
return false;
}
public boolean visit(MySqlReplaceStatement x) {
return true;
}
@Override
public boolean visit(SQLCallStatement x) {
return false;
}
}
@@ -27,6 +27,7 @@ import com.alibaba.druid.sql.ast.expr.SQLInListExpr;
import com.alibaba.druid.sql.ast.expr.SQLMethodInvokeExpr;
import com.alibaba.druid.sql.ast.expr.SQLPropertyExpr;
import com.alibaba.druid.sql.ast.statement.SQLAlterTableStatement;
import com.alibaba.druid.sql.ast.statement.SQLCallStatement;
import com.alibaba.druid.sql.ast.statement.SQLCreateTableStatement;
import com.alibaba.druid.sql.ast.statement.SQLDeleteStatement;
import com.alibaba.druid.sql.ast.statement.SQLDropTableStatement;
@@ -39,6 +40,7 @@ import com.alibaba.druid.sql.ast.statement.SQLSelectStatement;
import com.alibaba.druid.sql.ast.statement.SQLSetStatement;
import com.alibaba.druid.sql.ast.statement.SQLUnionQuery;
import com.alibaba.druid.sql.ast.statement.SQLUpdateStatement;
import com.alibaba.druid.sql.dialect.mysql.ast.statement.MySqlReplaceStatement;
import com.alibaba.druid.sql.dialect.oracle.ast.stmt.OracleSelectTableReference;
import com.alibaba.druid.sql.dialect.postgresql.ast.stmt.PGSelectQueryBlock;
import com.alibaba.druid.sql.dialect.postgresql.visitor.PGASTVisitorAdapter;
@@ -226,4 +228,13 @@ public class PGWallVisitor extends PGASTVisitorAdapter implements WallVisitor {
public boolean visit(SQLSetStatement x) {
return false;
}
public boolean visit(MySqlReplaceStatement x) {
return true;
}
@Override
public boolean visit(SQLCallStatement x) {
return false;
}
}
@@ -28,6 +28,7 @@ import com.alibaba.druid.sql.ast.expr.SQLMethodInvokeExpr;
import com.alibaba.druid.sql.ast.expr.SQLPropertyExpr;
import com.alibaba.druid.sql.ast.expr.SQLVariantRefExpr;
import com.alibaba.druid.sql.ast.statement.SQLAlterTableStatement;
import com.alibaba.druid.sql.ast.statement.SQLCallStatement;
import com.alibaba.druid.sql.ast.statement.SQLCreateTableStatement;
import com.alibaba.druid.sql.ast.statement.SQLDeleteStatement;
import com.alibaba.druid.sql.ast.statement.SQLDropTableStatement;
@@ -40,6 +41,7 @@ import com.alibaba.druid.sql.ast.statement.SQLSelectStatement;
import com.alibaba.druid.sql.ast.statement.SQLSetStatement;
import com.alibaba.druid.sql.ast.statement.SQLUnionQuery;
import com.alibaba.druid.sql.ast.statement.SQLUpdateStatement;
import com.alibaba.druid.sql.dialect.mysql.ast.statement.MySqlReplaceStatement;
import com.alibaba.druid.sql.dialect.sqlserver.ast.SQLServerSelectQueryBlock;
import com.alibaba.druid.sql.dialect.sqlserver.ast.expr.SQLServerObjectReferenceExpr;
import com.alibaba.druid.sql.dialect.sqlserver.ast.stmt.SQLServerInsertStatement;
@@ -257,4 +259,13 @@ public class SQLServerWallVisitor extends SQLServerASTVisitorAdapter implements
public boolean visit(SQLSetStatement x) {
return false;
}
public boolean visit(MySqlReplaceStatement x) {
return true;
}
@Override
public boolean visit(SQLCallStatement x) {
return false;
}
}
@@ -66,7 +66,9 @@ import com.alibaba.druid.sql.ast.statement.SQLTruncateStatement;
import com.alibaba.druid.sql.ast.statement.SQLUnionOperator;
import com.alibaba.druid.sql.ast.statement.SQLUnionQuery;
import com.alibaba.druid.sql.ast.statement.SQLUpdateStatement;
import com.alibaba.druid.sql.ast.statement.SQLUseStatement;
import com.alibaba.druid.sql.dialect.mysql.ast.expr.MySqlBooleanExpr;
import com.alibaba.druid.sql.dialect.mysql.ast.statement.MySqlCommitStatement;
import com.alibaba.druid.sql.dialect.mysql.ast.statement.MySqlDescribeStatement;
import com.alibaba.druid.sql.dialect.mysql.ast.statement.MySqlReplaceStatement;
import com.alibaba.druid.sql.dialect.mysql.ast.statement.MySqlSetCharSetStatement;
@@ -1059,6 +1061,12 @@ public class WallVisitorUtils {
} else if (x instanceof MySqlShowStatement) {
allow = config.isShowAllow();
denyMessage = "show not allow";
} else if (x instanceof MySqlCommitStatement) {
allow = config.isCommitAllow();
denyMessage = "show not allow";
} else if (x instanceof SQLUseStatement) {
allow = config.isUseAllow();
denyMessage = "show not allow";
} else {
allow = config.isNoneBaseStatementAllow();
}
@@ -18,4 +18,5 @@ sql_big_selects
sql_big_tables
sql_mode
tx_isolation
warning_count
warning_count
@ret
@@ -32,7 +32,7 @@ public class WallStatTest_blackList_1 extends TestCase {
Assert.assertEquals(0, provider.getBlackListHitCount());
Assert.assertEquals(0, provider.getWhiteListHitCount());
Assert.assertEquals(0, provider.getWhiteList().size());
Assert.assertEquals(500, provider.getBlackList().size());
Assert.assertEquals(100, provider.getBlackList().size());
Assert.assertEquals(1001, provider.getCheckCount());
}
@@ -1,5 +1,6 @@
package com.alibaba.druid.bvt.filter.wall;
import java.util.Collection;
import java.util.Map;
import junit.framework.TestCase;
@@ -26,26 +27,39 @@ public class WallStatTest_statMap extends TestCase {
WallProvider providerA = new MySqlWallProvider();
{
String sql = "select * from t where len(fname) = 1";
Assert.assertTrue(providerA.checkValid(sql));
String sql = "select * from t where len(fname) = 1 OR 1 = 1";
Assert.assertFalse(providerA.checkValid(sql));
}
WallProvider providerB = new MySqlWallProvider();
{
String sql = "select * from t where len(fname) = 2";
Assert.assertTrue(providerB.checkValid(sql));
String sql = "select * from t where len(fname) = 2 OR 1 = 1";
Assert.assertFalse(providerB.checkValid(sql));
}
WallProvider providerC = new MySqlWallProvider();
{
String sql = "select * from t where len(fname) = 2 OR 1 = 1";
Assert.assertFalse(providerC.checkValid(sql));
}
Map<String, Object> statMapA = providerA.getStatsMap();
Map<String, Object> statMapB = providerB.getStatsMap();
Map<String, Object> statMapC = providerC.getStatsMap();
System.out.println(JSONUtils.toJSONString(statMapA));
System.out.println(JSONUtils.toJSONString(statMapB));
System.out.println(JSONUtils.toJSONString(statMapC));
Map<String, Object> statMapMerged = DruidStatManagerFacade.mergWallStat(statMapA, statMapB);
System.out.println(JSONUtils.toJSONString(statMapMerged));
Assert.assertEquals(2L, statMapMerged.get("checkCount"));
Assert.assertEquals(2, ((Collection<String>) statMapMerged.get("blackList")).size());
statMapMerged = DruidStatManagerFacade.mergWallStat(statMapMerged, statMapC);
System.out.println(JSONUtils.toJSONString(statMapMerged));
Assert.assertEquals(2, ((Collection<String>) statMapMerged.get("blackList")).size());
}
}