diff --git a/src/main/java/com/alibaba/druid/filter/wall/WallConfig.java b/src/main/java/com/alibaba/druid/filter/wall/WallConfig.java index f97f88d18a..f2c3bfaf95 100644 --- a/src/main/java/com/alibaba/druid/filter/wall/WallConfig.java +++ b/src/main/java/com/alibaba/druid/filter/wall/WallConfig.java @@ -27,14 +27,18 @@ public class WallConfig { private boolean insertAllow = true; private boolean mergeAllow = true; + private boolean truncateAllow = false; + private boolean shcemaCheck = true; private boolean tableCheck = true; private boolean functionCheck = true; + private boolean objectCheck = true; + private boolean variantCheck = true; protected final Set permitFunctions = new HashSet(); protected final Set permitTables = new HashSet(); protected final Set permitSchemas = new HashSet(); - protected final Set permitNames = new HashSet(); + protected final Set permitVariants = new HashSet(); protected final Set permitObjects = new HashSet(); private String dir; @@ -71,7 +75,7 @@ public class WallConfig { dir = dir.substring(0, dir.length() - 1); } - loadResource(getPermitNames(), dir + "/permit-name.txt"); + loadResource(getPermitVariants(), dir + "/permit-var.txt"); loadResource(getPermitSchemas(), dir + "/permit-schema.txt"); loadResource(getPermitFunctions(), dir + "/permit-function.txt"); loadResource(getPermitTables(), dir + "/permit-table.txt"); @@ -86,6 +90,14 @@ public class WallConfig { this.noneBaseStatementAllow = noneBaseStatementAllow; } + public boolean isTruncateAllow() { + return truncateAllow; + } + + public void setTruncateAllow(boolean truncateAllow) { + this.truncateAllow = truncateAllow; + } + public boolean isSelelctAllow() { return selelctAllow; } @@ -206,6 +218,22 @@ public class WallConfig { this.functionCheck = functionCheck; } + public boolean isVariantCheck() { + return variantCheck; + } + + public void setVariantCheck(boolean variantCheck) { + this.variantCheck = variantCheck; + } + + public boolean isObjectCheck() { + return objectCheck; + } + + public void setObjectCheck(boolean objectCheck) { + this.objectCheck = objectCheck; + } + // /////////////////// public Set getPermitFunctions() { @@ -220,8 +248,8 @@ public class WallConfig { return permitSchemas; } - public Set getPermitNames() { - return permitNames; + public Set getPermitVariants() { + return permitVariants; } public Set getPermitObjects() { diff --git a/src/main/java/com/alibaba/druid/filter/wall/WallVisitor.java b/src/main/java/com/alibaba/druid/filter/wall/WallVisitor.java index 035fb94ada..db434abf60 100644 --- a/src/main/java/com/alibaba/druid/filter/wall/WallVisitor.java +++ b/src/main/java/com/alibaba/druid/filter/wall/WallVisitor.java @@ -11,7 +11,7 @@ public interface WallVisitor extends SQLASTVisitor { List getViolations(); - boolean containsPermitTable(String name); + boolean isPermitTable(String name); String toSQL(SQLObject obj); } 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 907e0398b4..7608428884 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 @@ -22,6 +22,7 @@ import com.alibaba.druid.sql.ast.statement.SQLInsertStatement; import com.alibaba.druid.sql.ast.statement.SQLSelectGroupByClause; import com.alibaba.druid.sql.ast.statement.SQLSelectQueryBlock; import com.alibaba.druid.sql.ast.statement.SQLSelectStatement; +import com.alibaba.druid.sql.ast.statement.SQLTruncateStatement; 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; @@ -142,7 +143,7 @@ public class MySqlWallVisitor extends MySqlASTVisitorAdapter implements WallVisi } if (varName.startsWith("@@")) { - violations.add(new IllegalSQLObjectViolation(SQLUtils.toMySqlString(x))); + violations.add(new IllegalSQLObjectViolation(toSQL(x))); } return false; @@ -168,7 +169,7 @@ public class MySqlWallVisitor extends MySqlASTVisitorAdapter implements WallVisi @Override public boolean visit(MySqlOutFileExpr x) { if (!config.isSelectIntoOutfileAllow()) { - violations.add(new IllegalSQLObjectViolation(SQLUtils.toMySqlString(x))); + violations.add(new IllegalSQLObjectViolation(toSQL(x))); } return true; @@ -187,7 +188,7 @@ public class MySqlWallVisitor extends MySqlASTVisitorAdapter implements WallVisi } @Override - public boolean containsPermitTable(String name) { + public boolean isPermitTable(String name) { if (!config.isTableCheck()) { return false; } @@ -212,9 +213,13 @@ public class MySqlWallVisitor extends MySqlASTVisitorAdapter implements WallVisi } else if (x instanceof SQLDeleteStatement) { } else if (x instanceof SQLUpdateStatement) { - + + } else if (x instanceof SQLTruncateStatement) { + if (!config.isTruncateAllow()) { + violations.add(new IllegalSQLObjectViolation(toSQL(x))); + } } else { - violations.add(new IllegalSQLObjectViolation(SQLUtils.toMySqlString(x))); + violations.add(new IllegalSQLObjectViolation(toSQL(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 b72a1be59f..a4e9dfdc74 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 @@ -21,6 +21,7 @@ import com.alibaba.druid.sql.ast.statement.SQLInsertStatement; import com.alibaba.druid.sql.ast.statement.SQLSelectGroupByClause; import com.alibaba.druid.sql.ast.statement.SQLSelectQueryBlock; import com.alibaba.druid.sql.ast.statement.SQLSelectStatement; +import com.alibaba.druid.sql.ast.statement.SQLTruncateStatement; 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.OracleDeleteStatement; @@ -50,7 +51,11 @@ public class OracleWallVisitor extends OracleASTVIsitorAdapter implements WallVi } public boolean visit(SQLIdentifierExpr x) { - + String name = x.getName(); + name = WallVisitorUtils.form(name); + if (config.getPermitVariants().contains(name)) { + getViolations().add(new IllegalSQLObjectViolation(toSQL(x))); + } return true; } @@ -118,7 +123,7 @@ public class OracleWallVisitor extends OracleASTVIsitorAdapter implements WallVi } @Override - public boolean containsPermitTable(String name) { + public boolean isPermitTable(String name) { if (!config.isTableCheck()) { return false; } @@ -147,8 +152,11 @@ public class OracleWallVisitor extends OracleASTVIsitorAdapter implements WallVi } else if (x instanceof SQLUpdateStatement) { } else if (x instanceof OracleMultiInsertStatement) { - } else if (x instanceof OracleMergeStatement) { + } else if (x instanceof SQLTruncateStatement) { + if (!config.isTruncateAllow()) { + violations.add(new IllegalSQLObjectViolation(toSQL(x))); + } } else { violations.add(new IllegalSQLObjectViolation(toSQL(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 86bcb5417e..cc14809ceb 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 @@ -441,7 +441,7 @@ public class WallVisitorUtils { if (tableName != null) { tableName = form(tableName); - if (visitor.containsPermitTable(tableName)) { + if (visitor.isPermitTable(tableName)) { addViolation(visitor, x); } } diff --git a/src/main/java/com/alibaba/druid/sql/dialect/oracle/ast/stmt/OracleExceptionStatement.java b/src/main/java/com/alibaba/druid/sql/dialect/oracle/ast/stmt/OracleExceptionStatement.java index 76165444ea..b02436a002 100644 --- a/src/main/java/com/alibaba/druid/sql/dialect/oracle/ast/stmt/OracleExceptionStatement.java +++ b/src/main/java/com/alibaba/druid/sql/dialect/oracle/ast/stmt/OracleExceptionStatement.java @@ -8,7 +8,7 @@ import com.alibaba.druid.sql.ast.SQLStatement; import com.alibaba.druid.sql.dialect.oracle.ast.OracleSQLObjectImpl; import com.alibaba.druid.sql.dialect.oracle.visitor.OracleASTVisitor; -public class OracleExceptionStatement extends OracleSQLObjectImpl implements OracleStatement { +public class OracleExceptionStatement extends OracleStatementImpl implements OracleStatement { private static final long serialVersionUID = 1L; private List items = new ArrayList(); diff --git a/src/main/java/com/alibaba/druid/sql/dialect/oracle/ast/stmt/OracleGrantStatement.java b/src/main/java/com/alibaba/druid/sql/dialect/oracle/ast/stmt/OracleGrantStatement.java index 73eeec0c85..b321f7fa07 100644 --- a/src/main/java/com/alibaba/druid/sql/dialect/oracle/ast/stmt/OracleGrantStatement.java +++ b/src/main/java/com/alibaba/druid/sql/dialect/oracle/ast/stmt/OracleGrantStatement.java @@ -4,10 +4,9 @@ import java.util.ArrayList; import java.util.List; import com.alibaba.druid.sql.ast.SQLExpr; -import com.alibaba.druid.sql.dialect.oracle.ast.OracleSQLObjectImpl; import com.alibaba.druid.sql.dialect.oracle.visitor.OracleASTVisitor; -public class OracleGrantStatement extends OracleSQLObjectImpl implements OracleStatement { +public class OracleGrantStatement extends OracleStatementImpl implements OracleStatement { private static final long serialVersionUID = 1L; diff --git a/src/main/resources/META-INF/druid/wall/oracle/permit-name.txt b/src/main/resources/META-INF/druid/wall/oracle/permit-variant.txt similarity index 100% rename from src/main/resources/META-INF/druid/wall/oracle/permit-name.txt rename to src/main/resources/META-INF/druid/wall/oracle/permit-variant.txt diff --git a/src/test/java/com/alibaba/druid/bvt/filter/wall/OracleWallPermitVariantTest.java b/src/test/java/com/alibaba/druid/bvt/filter/wall/OracleWallPermitVariantTest.java new file mode 100644 index 0000000000..e726d6efeb --- /dev/null +++ b/src/test/java/com/alibaba/druid/bvt/filter/wall/OracleWallPermitVariantTest.java @@ -0,0 +1,26 @@ +package com.alibaba.druid.bvt.filter.wall; + +import junit.framework.TestCase; + +import org.junit.Assert; + +import com.alibaba.druid.filter.wall.WallConfig; +import com.alibaba.druid.filter.wall.WallUtils; + +/** + * 这个场景测试访问Oracle系统对象 + * + * @author admin + */ +public class OracleWallPermitVariantTest extends TestCase { + + public void test_permitTable() throws Exception { + WallConfig config = new WallConfig(); + config.setVariantCheck(false); + + Assert.assertTrue(WallUtils.isValidateOracle("select UID from dual")); + Assert.assertTrue(WallUtils.isValidateOracle("select USER from dual")); + Assert.assertTrue(WallUtils.isValidateOracle("select user from dual")); + } + +} diff --git a/src/test/java/com/alibaba/druid/bvt/filter/wall/OracleWallPermitVariantTest2.java b/src/test/java/com/alibaba/druid/bvt/filter/wall/OracleWallPermitVariantTest2.java new file mode 100644 index 0000000000..9f8c44d9aa --- /dev/null +++ b/src/test/java/com/alibaba/druid/bvt/filter/wall/OracleWallPermitVariantTest2.java @@ -0,0 +1,21 @@ +package com.alibaba.druid.bvt.filter.wall; + +import junit.framework.TestCase; + +import org.junit.Assert; + +import com.alibaba.druid.filter.wall.WallUtils; + +/** + * 这个场景测试访问Oracle系统对象 + * + * @author admin + */ +public class OracleWallPermitVariantTest2 extends TestCase { + + public void test_permitTable() throws Exception { + Assert.assertFalse(WallUtils.isValidateOracle("select UID from dual")); + Assert.assertFalse(WallUtils.isValidateOracle("select USER from dual")); + } + +} diff --git a/src/test/java/com/alibaba/druid/bvt/filter/wall/WallTruncateTest.java b/src/test/java/com/alibaba/druid/bvt/filter/wall/WallTruncateTest.java new file mode 100644 index 0000000000..45b834c498 --- /dev/null +++ b/src/test/java/com/alibaba/druid/bvt/filter/wall/WallTruncateTest.java @@ -0,0 +1,32 @@ +package com.alibaba.druid.bvt.filter.wall; + +import junit.framework.TestCase; + +import org.junit.Assert; + +import com.alibaba.druid.filter.wall.WallConfig; +import com.alibaba.druid.filter.wall.WallUtils; + +/** + * 这个场景,检测 + * @author wenshao + * + */ +public class WallTruncateTest extends TestCase { + private String sql = "TRUNCATE TABLE T1"; + + private WallConfig config = new WallConfig(); + + protected void setUp() throws Exception { + //config.setTruncateAllow(true); + } + + public void testMySql() throws Exception { + Assert.assertFalse(WallUtils.isValidateMySql(sql, config)); + } + + public void testORACLE() throws Exception { + + Assert.assertFalse(WallUtils.isValidateOracle(sql, config)); + } +} diff --git a/src/test/java/com/alibaba/druid/bvt/filter/wall/WallTruncateTest1.java b/src/test/java/com/alibaba/druid/bvt/filter/wall/WallTruncateTest1.java new file mode 100644 index 0000000000..95260b5ecb --- /dev/null +++ b/src/test/java/com/alibaba/druid/bvt/filter/wall/WallTruncateTest1.java @@ -0,0 +1,32 @@ +package com.alibaba.druid.bvt.filter.wall; + +import junit.framework.TestCase; + +import org.junit.Assert; + +import com.alibaba.druid.filter.wall.WallConfig; +import com.alibaba.druid.filter.wall.WallUtils; + +/** + * 这个场景,检测 + * @author wenshao + * + */ +public class WallTruncateTest1 extends TestCase { + private String sql = "TRUNCATE TABLE T1"; + + private WallConfig config = new WallConfig(); + + protected void setUp() throws Exception { + config.setTruncateAllow(true); + } + + public void testMySql() throws Exception { + Assert.assertTrue(WallUtils.isValidateMySql(sql, config)); + } + + public void testORACLE() throws Exception { + + Assert.assertTrue(WallUtils.isValidateOracle(sql, config)); + } +} diff --git a/src/test/java/com/alibaba/druid/sql/OnlineOracleTest3.java b/src/test/java/com/alibaba/druid/sql/OnlineOracleTest3.java index cfe738d3c1..5558624799 100644 --- a/src/test/java/com/alibaba/druid/sql/OnlineOracleTest3.java +++ b/src/test/java/com/alibaba/druid/sql/OnlineOracleTest3.java @@ -34,7 +34,7 @@ public class OnlineOracleTest3 extends TestCase { } public void test_connect() throws Exception { - executeQuery("select * from all_users"); + executeQuery("select UID, USER FROM DUAL"); } public void executeQuery(String sql) throws SQLException {