diff --git a/src/main/java/com/alibaba/druid/filter/wall/spi/MySqlWallVisitor.java b/src/main/java/com/alibaba/druid/filter/wall/spi/MySqlWallVisitor.java index 7fa6a35dc4..b63faffd3f 100644 --- a/src/main/java/com/alibaba/druid/filter/wall/spi/MySqlWallVisitor.java +++ b/src/main/java/com/alibaba/druid/filter/wall/spi/MySqlWallVisitor.java @@ -11,22 +11,23 @@ import com.alibaba.druid.filter.wall.WallVisitor; import com.alibaba.druid.sql.SQLUtils; import com.alibaba.druid.sql.ast.SQLName; import com.alibaba.druid.sql.ast.SQLObject; +import com.alibaba.druid.sql.ast.SQLStatement; import com.alibaba.druid.sql.ast.expr.SQLBinaryOpExpr; import com.alibaba.druid.sql.ast.expr.SQLMethodInvokeExpr; import com.alibaba.druid.sql.ast.expr.SQLVariantRefExpr; -import com.alibaba.druid.sql.ast.statement.SQLDropTableStatement; +import com.alibaba.druid.sql.ast.statement.SQLDeleteStatement; import com.alibaba.druid.sql.ast.statement.SQLExprTableSource; +import com.alibaba.druid.sql.ast.statement.SQLInsertStatement; import com.alibaba.druid.sql.ast.statement.SQLSelectQueryBlock; +import com.alibaba.druid.sql.ast.statement.SQLSelectStatement; import com.alibaba.druid.sql.ast.statement.SQLUnionQuery; +import com.alibaba.druid.sql.ast.statement.SQLUpdateStatement; import com.alibaba.druid.sql.dialect.mysql.ast.expr.MySqlOutFileExpr; -import com.alibaba.druid.sql.dialect.mysql.ast.statement.MySqlExecuteStatement; import com.alibaba.druid.sql.dialect.mysql.ast.statement.MySqlSelectQueryBlock; -import com.alibaba.druid.sql.dialect.mysql.ast.statement.MySqlShowColumnsStatement; -import com.alibaba.druid.sql.dialect.mysql.ast.statement.MySqlShowDatabasesStatement; -import com.alibaba.druid.sql.dialect.mysql.ast.statement.MySqlShowTablesStatement; +import com.alibaba.druid.sql.dialect.mysql.visitor.MySqlASTVisitor; import com.alibaba.druid.sql.dialect.mysql.visitor.MySqlASTVisitorAdapter; -public class MySqlWallVisitor extends MySqlASTVisitorAdapter implements WallVisitor { +public class MySqlWallVisitor extends MySqlASTVisitorAdapter implements WallVisitor, MySqlASTVisitor { private final Set permitFunctions = new HashSet(); private final Set permitTables = new HashSet(); @@ -79,29 +80,6 @@ public class MySqlWallVisitor extends MySqlASTVisitorAdapter implements WallVisi return violations; } - public boolean visit(MySqlExecuteStatement x) { - violations.add(new IllegalSQLObjectViolation(SQLUtils.toMySqlString(x))); - return false; - } - - @Override - public boolean visit(MySqlShowTablesStatement x) { - violations.add(new IllegalSQLObjectViolation(SQLUtils.toMySqlString(x))); - return false; - } - - @Override - public boolean visit(MySqlShowDatabasesStatement x) { - violations.add(new IllegalSQLObjectViolation(SQLUtils.toMySqlString(x))); - return false; - } - - @Override - public boolean visit(MySqlShowColumnsStatement x) { - violations.add(new IllegalSQLObjectViolation(SQLUtils.toMySqlString(x))); - return false; - } - public boolean visit(SQLBinaryOpExpr x) { WallVisitorUtils.check(this, x); @@ -122,11 +100,6 @@ public class MySqlWallVisitor extends MySqlASTVisitorAdapter implements WallVisi return visit((SQLSelectQueryBlock) x); } - public boolean visit(SQLDropTableStatement x) { - violations.add(new IllegalSQLObjectViolation(SQLUtils.toMySqlString(x))); - return false; - } - public boolean visit(SQLVariantRefExpr x) { String varName = x.getName(); if (varName == null) { @@ -183,4 +156,21 @@ public class MySqlWallVisitor extends MySqlASTVisitorAdapter implements WallVisi return permitTables.contains(name); } + public void preVisit(SQLObject x) { + if (!(x instanceof SQLStatement)) { + return; + } + + if (x instanceof SQLInsertStatement) { + + } else if (x instanceof SQLSelectStatement) { + + } else if (x instanceof SQLDeleteStatement) { + + } else if (x instanceof SQLUpdateStatement) { + + } else { + violations.add(new IllegalSQLObjectViolation(SQLUtils.toMySqlString(x))); + } + } } diff --git a/src/main/java/com/alibaba/druid/filter/wall/spi/OracleWallVisitor.java b/src/main/java/com/alibaba/druid/filter/wall/spi/OracleWallVisitor.java index 4e1c4c78aa..42e85afae0 100644 --- a/src/main/java/com/alibaba/druid/filter/wall/spi/OracleWallVisitor.java +++ b/src/main/java/com/alibaba/druid/filter/wall/spi/OracleWallVisitor.java @@ -1,12 +1,6 @@ package com.alibaba.druid.filter.wall.spi; -import java.io.BufferedReader; -import java.io.IOException; -import java.io.InputStream; -import java.io.InputStreamReader; -import java.net.URL; import java.util.ArrayList; -import java.util.Enumeration; import java.util.HashSet; import java.util.List; import java.util.Set; @@ -14,25 +8,27 @@ import java.util.Set; import com.alibaba.druid.filter.wall.IllegalSQLObjectViolation; import com.alibaba.druid.filter.wall.Violation; import com.alibaba.druid.filter.wall.WallVisitor; -import com.alibaba.druid.logging.Log; -import com.alibaba.druid.logging.LogFactory; import com.alibaba.druid.sql.SQLUtils; import com.alibaba.druid.sql.ast.SQLName; import com.alibaba.druid.sql.ast.SQLObject; +import com.alibaba.druid.sql.ast.SQLStatement; import com.alibaba.druid.sql.ast.expr.SQLBinaryOpExpr; import com.alibaba.druid.sql.ast.expr.SQLIdentifierExpr; import com.alibaba.druid.sql.ast.expr.SQLMethodInvokeExpr; +import com.alibaba.druid.sql.ast.statement.SQLDeleteStatement; import com.alibaba.druid.sql.ast.statement.SQLDropTableStatement; import com.alibaba.druid.sql.ast.statement.SQLExprTableSource; +import com.alibaba.druid.sql.ast.statement.SQLInsertStatement; +import com.alibaba.druid.sql.ast.statement.SQLSelectStatement; import com.alibaba.druid.sql.ast.statement.SQLUnionQuery; +import com.alibaba.druid.sql.ast.statement.SQLUpdateStatement; +import com.alibaba.druid.sql.dialect.oracle.ast.stmt.OracleMergeStatement; +import com.alibaba.druid.sql.dialect.oracle.ast.stmt.OracleMultiInsertStatement; import com.alibaba.druid.sql.dialect.oracle.ast.stmt.OracleSelectTableReference; import com.alibaba.druid.sql.dialect.oracle.visitor.OracleASTVIsitorAdapter; -import com.alibaba.druid.util.JdbcUtils; public class OracleWallVisitor extends OracleASTVIsitorAdapter implements WallVisitor { - private final static Log LOG = LogFactory.getLog(OracleWallVisitor.class); - private final Set permitFunctions = new HashSet(); private final Set permitTables = new HashSet(); private final Set permitSchemas = new HashSet(); @@ -55,40 +51,8 @@ public class OracleWallVisitor extends OracleASTVIsitorAdapter implements WallVi addPermitName("uid"); addPermitName("user"); - loadPermitTables(); - - } - - private void loadPermitTables() { - try { - Enumeration e = Thread.currentThread().getContextClassLoader().getResources("META-INF/druid-filter-wall-permit-function.txt"); - while (e.hasMoreElements()) { - URL url = e.nextElement(); - InputStream in = null; - BufferedReader reader = null; - try { - in = url.openStream(); - reader = new BufferedReader(new InputStreamReader(in)); - for (;;) { - String line = reader.readLine(); - if (line == null) { - break; - } - line = line.trim(); - if (line.length() > 0) { - addPermitTable(line); - } - } - - url.openStream(); - } finally { - JdbcUtils.close(reader); - JdbcUtils.close(in); - } - } - } catch (IOException e) { - LOG.error("load oracle permit tables errror", e); - } + WallVisitorUtils.loadResource(this.permitFunctions, "META-INF/druid-filter-wall-permit-function.txt"); + WallVisitorUtils.loadResource(this.permitTables, "META-INF/druid-filter-wall-permit-table.txt"); } public void addPermitName(String name) { @@ -100,13 +64,12 @@ public class OracleWallVisitor extends OracleASTVIsitorAdapter implements WallVi name = name.toLowerCase(); permitFunctions.add(name); } - + public void addPermitTable(String name) { name = name.toLowerCase(); permitTables.add(name); } - public Set getPermitNames() { return permitNames; } @@ -155,7 +118,7 @@ public class OracleWallVisitor extends OracleASTVIsitorAdapter implements WallVi WallVisitorUtils.check(this, x); return true; } - + public boolean visit(SQLExprTableSource x) { WallVisitorUtils.check(this, x); @@ -165,7 +128,7 @@ public class OracleWallVisitor extends OracleASTVIsitorAdapter implements WallVi return true; } - + @Override public boolean visit(SQLUnionQuery x) { if (WallVisitorUtils.queryBlockFromIsNull(x.getLeft()) || WallVisitorUtils.queryBlockFromIsNull(x.getRight())) { @@ -174,15 +137,35 @@ public class OracleWallVisitor extends OracleASTVIsitorAdapter implements WallVi return true; } - + @Override public String toSQL(SQLObject obj) { return SQLUtils.toOracleString(obj); } - + @Override public boolean containsPermitTable(String name) { name = WallVisitorUtils.form(name); return permitTables.contains(name); } + + public void preVisit(SQLObject x) { + if (!(x instanceof SQLStatement)) { + return; + } + + if (x instanceof SQLInsertStatement) { + + } else if (x instanceof SQLSelectStatement) { + + } else if (x instanceof SQLDeleteStatement) { + + } else if (x instanceof SQLUpdateStatement) { + } else if (x instanceof OracleMultiInsertStatement) { + + } else if (x instanceof OracleMergeStatement) { + } else { + violations.add(new IllegalSQLObjectViolation(SQLUtils.toMySqlString(x))); + } + } } diff --git a/src/main/java/com/alibaba/druid/filter/wall/spi/WallVisitorUtils.java b/src/main/java/com/alibaba/druid/filter/wall/spi/WallVisitorUtils.java index f88f3ab421..fd67c4080d 100644 --- a/src/main/java/com/alibaba/druid/filter/wall/spi/WallVisitorUtils.java +++ b/src/main/java/com/alibaba/druid/filter/wall/spi/WallVisitorUtils.java @@ -1,7 +1,17 @@ package com.alibaba.druid.filter.wall.spi; +import java.io.BufferedReader; +import java.io.IOException; +import java.io.InputStream; +import java.io.InputStreamReader; +import java.net.URL; +import java.util.Enumeration; +import java.util.Set; + import com.alibaba.druid.filter.wall.IllegalSQLObjectViolation; import com.alibaba.druid.filter.wall.WallVisitor; +import com.alibaba.druid.logging.Log; +import com.alibaba.druid.logging.LogFactory; import com.alibaba.druid.sql.SQLUtils; import com.alibaba.druid.sql.ast.SQLExpr; import com.alibaba.druid.sql.ast.SQLName; @@ -24,9 +34,12 @@ import com.alibaba.druid.sql.ast.statement.SQLSelectQueryBlock; import com.alibaba.druid.sql.ast.statement.SQLSubqueryTableSource; import com.alibaba.druid.sql.ast.statement.SQLTableSource; import com.alibaba.druid.sql.dialect.mysql.ast.expr.MySqlBooleanExpr; +import com.alibaba.druid.util.JdbcUtils; public class WallVisitorUtils { + private final static Log LOG = LogFactory.getLog(WallVisitorUtils.class); + public static void check(WallVisitor visitor, SQLBinaryOpExpr x) { if (Boolean.TRUE == getValue(x)) { visitor.getViolations().add(new IllegalSQLObjectViolation(SQLUtils.toSQLString(x))); @@ -209,15 +222,15 @@ public class WallVisitorUtils { return ((String) firstValue).length(); } } - + if ("if".equalsIgnoreCase(methodName) && x.getParameters().size() == 3) { SQLExpr first = x.getParameters().get(0); Object firstResult = getValue(first); - + if (Boolean.TRUE == firstResult) { return getValue(x.getParameters().get(1)); } - + if (Boolean.FALSE == firstResult) { getValue(x.getParameters().get(2)); } @@ -290,7 +303,7 @@ public class WallVisitorUtils { if (propExpr.getOwner() instanceof SQLIdentifierExpr) { String ownerName = ((SQLIdentifierExpr) propExpr.getOwner()).getName(); - + ownerName = form(ownerName); if (visitor.getPermitSchemas().contains(ownerName.toLowerCase())) { @@ -345,8 +358,41 @@ public class WallVisitorUtils { if (name.startsWith("`") && name.endsWith("`")) { name = name.substring(1, name.length() - 1); } - + name = name.toLowerCase(); return name; } + + public static void loadResource(Set names, String resource) { + try { + Enumeration e = Thread.currentThread().getContextClassLoader().getResources("META-INF/druid-filter-wall-permit-function.txt"); + while (e.hasMoreElements()) { + URL url = e.nextElement(); + InputStream in = null; + BufferedReader reader = null; + try { + in = url.openStream(); + reader = new BufferedReader(new InputStreamReader(in)); + for (;;) { + String line = reader.readLine(); + if (line == null) { + break; + } + line = line.trim(); + if (line.length() > 0) { + line = line.toLowerCase(); + names.add(line); + } + } + + url.openStream(); + } finally { + JdbcUtils.close(reader); + JdbcUtils.close(in); + } + } + } catch (IOException e) { + LOG.error("load oracle permit tables errror", e); + } + } } diff --git a/src/main/resources/META-INF/druid-filter-wall-permit-function.txt b/src/main/resources/META-INF/druid-filter-wall-permit-table.txt similarity index 100% rename from src/main/resources/META-INF/druid-filter-wall-permit-function.txt rename to src/main/resources/META-INF/druid-filter-wall-permit-table.txt diff --git a/src/test/java/com/alibaba/druid/bvt/filter/wall/MySqlWallLoadDataInfileTest.java b/src/test/java/com/alibaba/druid/bvt/filter/wall/MySqlWallLoadDataInfileTest.java new file mode 100644 index 0000000000..bee14922c8 --- /dev/null +++ b/src/test/java/com/alibaba/druid/bvt/filter/wall/MySqlWallLoadDataInfileTest.java @@ -0,0 +1,20 @@ +package com.alibaba.druid.bvt.filter.wall; + +import org.junit.Assert; + +import com.alibaba.druid.filter.wall.WallUtils; + +import junit.framework.TestCase; + +/** + * 这个场景测试访问MySql系统函数 + * + * @author admin + */ +public class MySqlWallLoadDataInfileTest extends TestCase { + + public void test_permit_stmt() throws Exception { + Assert.assertFalse(WallUtils.isValidateMySql("load data infile 'c:/boot.ini' into table foo")); + } + +} diff --git a/src/test/java/com/alibaba/druid/bvt/filter/wall/MySqlWallPermitFunctionTest.java b/src/test/java/com/alibaba/druid/bvt/filter/wall/MySqlWallPermitFunctionTest.java new file mode 100644 index 0000000000..3e475a2ef0 --- /dev/null +++ b/src/test/java/com/alibaba/druid/bvt/filter/wall/MySqlWallPermitFunctionTest.java @@ -0,0 +1,29 @@ +package com.alibaba.druid.bvt.filter.wall; + +import org.junit.Assert; + +import com.alibaba.druid.filter.wall.WallUtils; + +import junit.framework.TestCase; + +/** + * 这个场景测试访问MySql系统表 + * + * @author admin + */ +public class MySqlWallPermitFunctionTest extends TestCase { + + public void test_permitTable() throws Exception { + Assert.assertFalse(WallUtils.isValidateMySql("SELECT User,Password FROM mysql.user")); + Assert.assertFalse(WallUtils.isValidateMySql("SELECT User,Password FROM `mysql`.`user`")); + Assert.assertFalse(WallUtils.isValidateMySql("SELECT User,Password FROM \"mysql\".\"user\"")); + Assert.assertFalse(WallUtils.isValidateMySql("SELECT User,Password FROM MYSQL.USER")); + } + + public void test_permitTable_subquery() throws Exception { + Assert.assertFalse(WallUtils.isValidateMySql("select * from(SELECT User,Password FROM mysql.user) a")); + Assert.assertFalse(WallUtils.isValidateMySql("select * from(SELECT User,Password FROM `mysql`.`user`) a")); + Assert.assertFalse(WallUtils.isValidateMySql("select * from(SELECT User,Password FROM \"mysql\".\"user\") a")); + Assert.assertFalse(WallUtils.isValidateMySql("select * from(SELECT User,Password FROM MYSQL.USER) a")); + } +} diff --git a/src/test/java/com/alibaba/druid/bvt/filter/wall/MySqlWallPermitTableTest.java b/src/test/java/com/alibaba/druid/bvt/filter/wall/MySqlWallPermitTableTest.java index 5ce75768a7..fd0237ac74 100644 --- a/src/test/java/com/alibaba/druid/bvt/filter/wall/MySqlWallPermitTableTest.java +++ b/src/test/java/com/alibaba/druid/bvt/filter/wall/MySqlWallPermitTableTest.java @@ -7,23 +7,14 @@ import com.alibaba.druid.filter.wall.WallUtils; import junit.framework.TestCase; /** - * 这个场景测试访问MySql系统表 + * 这个场景测试访问MySql系统函数 * * @author admin */ public class MySqlWallPermitTableTest extends TestCase { public void test_permitTable() throws Exception { - Assert.assertFalse(WallUtils.isValidateMySql("SELECT User,Password FROM mysql.user")); - Assert.assertFalse(WallUtils.isValidateMySql("SELECT User,Password FROM `mysql`.`user`")); - Assert.assertFalse(WallUtils.isValidateMySql("SELECT User,Password FROM \"mysql\".\"user\"")); - Assert.assertFalse(WallUtils.isValidateMySql("SELECT User,Password FROM MYSQL.USER")); + Assert.assertFalse(WallUtils.isValidateMySql("select benchmark( 500000, sha1( 'test' ) )")); } - public void test_permitTable_subquery() throws Exception { - Assert.assertFalse(WallUtils.isValidateMySql("select * from(SELECT User,Password FROM mysql.user) a")); - Assert.assertFalse(WallUtils.isValidateMySql("select * from(SELECT User,Password FROM `mysql`.`user`) a")); - Assert.assertFalse(WallUtils.isValidateMySql("select * from(SELECT User,Password FROM \"mysql\".\"user\") a")); - Assert.assertFalse(WallUtils.isValidateMySql("select * from(SELECT User,Password FROM MYSQL.USER) a")); - } } diff --git a/src/test/java/com/alibaba/druid/sql/OnlineOracleTest3.java b/src/test/java/com/alibaba/druid/sql/OnlineOracleTest3.java index 23e858cf73..dc2984c740 100644 --- a/src/test/java/com/alibaba/druid/sql/OnlineOracleTest3.java +++ b/src/test/java/com/alibaba/druid/sql/OnlineOracleTest3.java @@ -33,7 +33,7 @@ public class OnlineOracleTest3 extends TestCase { } public void test_connect() throws Exception { - executeQuery("select * from TAB"); + executeQuery("select * from \"SYS\".TAB"); } public void executeQuery(String sql) throws SQLException { diff --git a/src/test/java/com/alibaba/druid/sql/TestOnlineSQLTest3.java b/src/test/java/com/alibaba/druid/sql/TestOnlineSQLTest3.java index f2db86feda..9cc0dfaa3e 100644 --- a/src/test/java/com/alibaba/druid/sql/TestOnlineSQLTest3.java +++ b/src/test/java/com/alibaba/druid/sql/TestOnlineSQLTest3.java @@ -33,7 +33,7 @@ public class TestOnlineSQLTest3 extends TestCase { // ResultSet rs = conn.getMetaData().getTables(null, null, null, null); // JdbcUtils.printResultSet(rs); - String sql = "SELECT User,Password FROM mysql.user;"; + String sql = "select benchmark( 1, sha1( 'test' ) )"; Statement stmt = conn.createStatement(); ResultSet rs = stmt.executeQuery(sql);