mirror of
https://github.com/alibaba/druid.git
synced 2023-03-04 19:17:16 +00:00
improve sql wall
This commit is contained in:
@@ -91,7 +91,6 @@ import com.alibaba.druid.sql.visitor.functions.Ucase;
|
||||
import com.alibaba.druid.sql.visitor.functions.Unhex;
|
||||
import com.alibaba.druid.util.HexBin;
|
||||
import com.alibaba.druid.util.JdbcUtils;
|
||||
import com.alibaba.druid.wall.WallContext;
|
||||
import com.alibaba.druid.wall.spi.WallVisitorUtils;
|
||||
import com.alibaba.druid.wall.spi.WallVisitorUtils.WallConditionContext;
|
||||
import com.alibaba.druid.wall.spi.WallVisitorUtils.WallSelectQueryContext;
|
||||
|
||||
@@ -55,12 +55,14 @@ public abstract class WallProvider {
|
||||
0.75f,
|
||||
1);
|
||||
|
||||
private boolean whiteListEnable = true;
|
||||
private LRUCache<String, WallSqlStat> whiteList;
|
||||
|
||||
private int MAX_SQL_LENGTH = 2048; // 1k
|
||||
|
||||
private int whiteSqlMaxSize = 500; // 1k
|
||||
|
||||
private boolean blackListEnable = true;
|
||||
private LRUCache<String, WallSqlStat> blackList;
|
||||
private LRUCache<String, WallSqlStat> blackMergedList;
|
||||
|
||||
@@ -239,6 +241,12 @@ public abstract class WallProvider {
|
||||
|
||||
public WallSqlStat addWhiteSql(String sql, Map<String, WallSqlTableStat> tableStats,
|
||||
Map<String, WallSqlFunctionStat> functionStats, boolean syntaxError) {
|
||||
|
||||
if (!whiteListEnable) {
|
||||
WallSqlStat stat = new WallSqlStat(tableStats, functionStats, syntaxError);
|
||||
return stat;
|
||||
}
|
||||
|
||||
String mergedSql;
|
||||
try {
|
||||
mergedSql = ParameterizedOutputVisitorUtils.parameterize(sql, dbType);
|
||||
@@ -306,6 +314,11 @@ public abstract class WallProvider {
|
||||
public WallSqlStat addBlackSql(String sql, Map<String, WallSqlTableStat> tableStats,
|
||||
Map<String, WallSqlFunctionStat> functionStats, List<Violation> violations,
|
||||
boolean syntaxError) {
|
||||
if (!blackListEnable) {
|
||||
WallSqlStat stat = new WallSqlStat(tableStats, functionStats, syntaxError);
|
||||
return stat;
|
||||
}
|
||||
|
||||
String mergedSql;
|
||||
try {
|
||||
mergedSql = ParameterizedOutputVisitorUtils.parameterize(sql, dbType);
|
||||
@@ -364,7 +377,7 @@ public abstract class WallProvider {
|
||||
if (whiteList != null) {
|
||||
hashSet.addAll(whiteList.keySet());
|
||||
}
|
||||
|
||||
|
||||
if (blackMergedList != null) {
|
||||
hashSet.addAll(blackMergedList.keySet());
|
||||
}
|
||||
@@ -705,7 +718,7 @@ public abstract class WallProvider {
|
||||
}
|
||||
|
||||
private WallCheckResult checkWhiteAndBlackList(String sql) {
|
||||
{
|
||||
if (whiteListEnable) {
|
||||
WallSqlStat sqlStat = getWhiteSql(sql);
|
||||
if (sqlStat != null) {
|
||||
whiteListHitCount.incrementAndGet();
|
||||
@@ -724,7 +737,7 @@ public abstract class WallProvider {
|
||||
}
|
||||
}
|
||||
// check black list
|
||||
{
|
||||
if (blackListEnable) {
|
||||
WallSqlStat sqlStat = getBlackSql(sql);
|
||||
if (sqlStat != null) {
|
||||
blackListHitCount.incrementAndGet();
|
||||
@@ -919,14 +932,14 @@ public abstract class WallProvider {
|
||||
}
|
||||
|
||||
sqlStatValue.setSql(sql);
|
||||
|
||||
|
||||
long sqlHash = sqlStat.getSqlHash();
|
||||
if (sqlHash == 0) {
|
||||
sqlHash = Utils.murmurhash2_64(sql);
|
||||
sqlStat.setSqlHash(sqlHash);
|
||||
}
|
||||
sqlStatValue.setSqlHash(sqlHash);
|
||||
|
||||
|
||||
statValue.getWhiteList().add(sqlStatValue);
|
||||
}
|
||||
}
|
||||
@@ -955,4 +968,20 @@ public abstract class WallProvider {
|
||||
public Map<String, Object> getStatsMap() {
|
||||
return getStatValue(false).toMap();
|
||||
}
|
||||
|
||||
public boolean isWhiteListEnable() {
|
||||
return whiteListEnable;
|
||||
}
|
||||
|
||||
public void setWhiteListEnable(boolean whiteListEnable) {
|
||||
this.whiteListEnable = whiteListEnable;
|
||||
}
|
||||
|
||||
public boolean isBlackListEnable() {
|
||||
return blackListEnable;
|
||||
}
|
||||
|
||||
public void setBlackListEnable(boolean blackListEnable) {
|
||||
this.blackListEnable = blackListEnable;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1011,15 +1011,16 @@ public class WallVisitorUtils {
|
||||
}
|
||||
}
|
||||
|
||||
String dbType = null;
|
||||
if (visitor != null) {
|
||||
dbType = visitor.getDbType();
|
||||
}
|
||||
|
||||
if (x instanceof SQLMethodInvokeExpr //
|
||||
|| x instanceof SQLBetweenExpr //
|
||||
|| x instanceof SQLInListExpr //
|
||||
|| x instanceof SQLUnaryExpr //
|
||||
) {
|
||||
String dbType = null;
|
||||
if (visitor != null) {
|
||||
dbType = visitor.getDbType();
|
||||
}
|
||||
return SQLEvalVisitorUtils.eval(dbType, x, Collections.emptyList(), false);
|
||||
}
|
||||
|
||||
@@ -1032,6 +1033,8 @@ public class WallVisitorUtils {
|
||||
addViolation(visitor, ErrorCode.CONST_CASE_CONDITION, "const case condition", caseExpr);
|
||||
}
|
||||
}
|
||||
|
||||
return SQLEvalVisitorUtils.eval(dbType, x, Collections.emptyList(), false);
|
||||
}
|
||||
|
||||
return null;
|
||||
|
||||
+79
@@ -0,0 +1,79 @@
|
||||
/*
|
||||
* Copyright 1999-2011 Alibaba Group Holding Ltd.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
package com.alibaba.druid.benckmark.wall;
|
||||
|
||||
import java.util.concurrent.CountDownLatch;
|
||||
|
||||
import junit.framework.TestCase;
|
||||
|
||||
import com.alibaba.druid.wall.WallProvider;
|
||||
import com.alibaba.druid.wall.spi.MySqlWallProvider;
|
||||
|
||||
public class WallBenchmarkTest_mysql_concurrent extends TestCase {
|
||||
|
||||
WallProvider provider = new MySqlWallProvider();
|
||||
|
||||
public final static int COUNT = 1000 * 10;
|
||||
|
||||
public void test_0() throws Exception {
|
||||
String sql = "SELECT t1.department_id, t2.*\n" + //
|
||||
"FROM hr_info t1, x2 t2\n" + //
|
||||
"WHERE t2.department_id = t1.department_id";
|
||||
for (int i = 0; i < 10; ++i) {
|
||||
provider.clearCache();
|
||||
long startMillis = System.currentTimeMillis();
|
||||
perf(sql, 10);
|
||||
long millis = System.currentTimeMillis() - startMillis;
|
||||
System.out.println("millis : " + millis);
|
||||
}
|
||||
}
|
||||
|
||||
public void perf(final String sql, int threadCount) {
|
||||
final CountDownLatch startLatch = new CountDownLatch(1);
|
||||
final CountDownLatch latch = new CountDownLatch(threadCount);
|
||||
for (int i = 0; i < threadCount; ++i) {
|
||||
final int seed = i * 1000 * 1000 * 100;
|
||||
Thread thread = new Thread() {
|
||||
|
||||
public void run() {
|
||||
try {
|
||||
startLatch.await();
|
||||
for (int i = 0; i < COUNT; ++i) {
|
||||
int id = seed + i;
|
||||
String text = sql + " AND FID = " + id;
|
||||
provider.check(text);
|
||||
}
|
||||
} catch (InterruptedException e) {
|
||||
e.printStackTrace();
|
||||
} finally {
|
||||
latch.countDown();
|
||||
}
|
||||
}
|
||||
};
|
||||
thread.setName("perf-" + i);
|
||||
thread.start();
|
||||
}
|
||||
|
||||
startLatch.countDown();
|
||||
|
||||
try {
|
||||
latch.await();
|
||||
} catch (InterruptedException e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,36 @@
|
||||
/*
|
||||
* Copyright 1999-2011 Alibaba Group Holding Ltd.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
package com.alibaba.druid.bvt.filter.wall;
|
||||
|
||||
import junit.framework.TestCase;
|
||||
|
||||
import org.junit.Assert;
|
||||
|
||||
import com.alibaba.druid.wall.WallProvider;
|
||||
import com.alibaba.druid.wall.spi.MySqlWallProvider;
|
||||
|
||||
public class MySqlWallTest128 extends TestCase {
|
||||
|
||||
public void test_false() throws Exception {
|
||||
WallProvider provider = new MySqlWallProvider();
|
||||
provider.getConfig().setCommentAllow(false);
|
||||
|
||||
String sql = "SELECT name, '******' password, createTime from user where name like 'admin' AND (CASE WHEN (7885=7885) THEN 1 ELSE 0 END)";
|
||||
|
||||
Assert.assertFalse(provider.checkValid(sql));
|
||||
}
|
||||
|
||||
}
|
||||
Reference in New Issue
Block a user