mirror of
https://github.com/alibaba/druid.git
synced 2023-03-04 19:17:16 +00:00
improve wall filter
This commit is contained in:
@@ -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());
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user