diff --git a/src/main/java/com/alibaba/druid/wall/WallProvider.java b/src/main/java/com/alibaba/druid/wall/WallProvider.java index 5dfba33679..9b5524aca9 100644 --- a/src/main/java/com/alibaba/druid/wall/WallProvider.java +++ b/src/main/java/com/alibaba/druid/wall/WallProvider.java @@ -49,6 +49,7 @@ public abstract class WallProvider { private final ConcurrentMap deniedTables = new ConcurrentHashMap(); private final ConcurrentMap deniedFunctions = new ConcurrentHashMap(); + private final ConcurrentMap deniedSchemas = new ConcurrentHashMap(); public WallProvider(WallConfig config){ this.config = config; @@ -146,6 +147,25 @@ public abstract class WallProvider { return true; } + + public boolean checkDenySchema(String schemaName) { + if (schemaName == null) { + return true; + } + + schemaName = schemaName.toLowerCase(); + if (getConfig().getDenySchemas().contains(schemaName)) { + WallDenyStat denyStat = this.deniedSchemas.get(schemaName); + if (denyStat == null) { + this.deniedSchemas.putIfAbsent(schemaName, new WallDenyStat()); + denyStat = this.deniedSchemas.get(schemaName); + } + denyStat.incrementAndGetDenyCount(); + return false; + } + + return true; + } public boolean checkDenyTable(String tableName) { if (tableName == null) { @@ -193,6 +213,15 @@ public abstract class WallProvider { String formName = WallVisitorUtils.form(tableName); return deniedTables.get(formName); } + + public WallDenyStat getDenniedSchemaStat(String schemaName) { + if (schemaName == null) { + return null; + } + + String formName = WallVisitorUtils.form(schemaName); + return deniedSchemas.get(formName); + } public WallCheckResult check(String sql) { WallCheckResult result = new WallCheckResult(); diff --git a/src/main/java/com/alibaba/druid/wall/spi/OracleWallVisitor.java b/src/main/java/com/alibaba/druid/wall/spi/OracleWallVisitor.java index e1137b6079..879fd738c1 100644 --- a/src/main/java/com/alibaba/druid/wall/spi/OracleWallVisitor.java +++ b/src/main/java/com/alibaba/druid/wall/spi/OracleWallVisitor.java @@ -112,8 +112,7 @@ public class OracleWallVisitor extends OracleASTVisitorAdapter implements WallVi } public boolean visit(OracleSelectTableReference x) { - WallVisitorUtils.check(this, x); - return true; + return WallVisitorUtils.check(this, x); } public boolean visit(SQLExprTableSource x) { diff --git a/src/main/java/com/alibaba/druid/wall/spi/SQLServerWallVisitor.java b/src/main/java/com/alibaba/druid/wall/spi/SQLServerWallVisitor.java index 87d32ee7b3..f38e6f4ffe 100644 --- a/src/main/java/com/alibaba/druid/wall/spi/SQLServerWallVisitor.java +++ b/src/main/java/com/alibaba/druid/wall/spi/SQLServerWallVisitor.java @@ -237,10 +237,10 @@ public class SQLServerWallVisitor extends SQLServerASTVisitorAdapter implements @Override public boolean visit(SQLServerObjectReferenceExpr x) { - if (x.getSchema() != null && config.isDenySchema(x.getSchema())) { + if (x.getSchema() != null && !provider.checkDenySchema(x.getSchema())) { this.getViolations().add(new IllegalSQLObjectViolation(this.toSQL(x))); } - if (x.getDatabase() != null && config.isDenySchema(x.getDatabase())) { + if (x.getDatabase() != null && !provider.checkDenySchema(x.getDatabase())) { this.getViolations().add(new IllegalSQLObjectViolation(this.toSQL(x))); } return true; diff --git a/src/main/java/com/alibaba/druid/wall/spi/WallVisitorUtils.java b/src/main/java/com/alibaba/druid/wall/spi/WallVisitorUtils.java index 9ce4d37728..f1d73b0637 100644 --- a/src/main/java/com/alibaba/druid/wall/spi/WallVisitorUtils.java +++ b/src/main/java/com/alibaba/druid/wall/spi/WallVisitorUtils.java @@ -741,38 +741,48 @@ public class WallVisitorUtils { } - private static void checkSchema(WallVisitor visitor, SQLExpr x) { + private static boolean checkSchema(WallVisitor visitor, SQLExpr x) { if (x instanceof SQLName) { String owner = ((SQLName) x).getSimleName(); owner = WallVisitorUtils.form(owner); - if (visitor.getConfig().isDenySchema(owner)) { + if (!visitor.getProvider().checkDenySchema(owner)) { addViolation(visitor, x); + return false; } if (visitor.getConfig().isDenyObjects(owner)) { addViolation(visitor, x); + return false; } } // if (ownerExpr instanceof SQLPropertyExpr) { if (x instanceof SQLPropertyExpr) { - checkSchema(visitor, ((SQLPropertyExpr) x).getOwner()); + return checkSchema(visitor, ((SQLPropertyExpr) x).getOwner()); } + + return true; } - public static void check(WallVisitor visitor, SQLExprTableSource x) { + public static boolean check(WallVisitor visitor, SQLExprTableSource x) { SQLExpr expr = x.getExpr(); if (expr instanceof SQLPropertyExpr) { - checkSchema(visitor, ((SQLPropertyExpr) expr).getOwner()); + boolean checkResult = checkSchema(visitor, ((SQLPropertyExpr) expr).getOwner()); + if (!checkResult) { + return false; + } } if (expr instanceof SQLName) { String tableName = ((SQLName) expr).getSimleName(); if (visitor.isDenyTable(tableName)) { addViolation(visitor, x); + return false; } } + + return true; } private static void addViolation(WallVisitor visitor, SQLObject x) { diff --git a/src/test/java/com/alibaba/druid/bvt/filter/wall/WallDenySchemaTest.java b/src/test/java/com/alibaba/druid/bvt/filter/wall/WallDenySchemaTest.java new file mode 100644 index 0000000000..89dc026d83 --- /dev/null +++ b/src/test/java/com/alibaba/druid/bvt/filter/wall/WallDenySchemaTest.java @@ -0,0 +1,38 @@ +/* + * 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.spi.OracleWallProvider; + +/** + * @author wenshao + * + */ +public class WallDenySchemaTest extends TestCase { + + public void testORACLE() throws Exception { + String sql = "SELECT F1, F2 FROM ALL_ALL_TABLES"; + + OracleWallProvider provider = new OracleWallProvider(); + Assert.assertFalse(provider.checkValid(sql)); + + Assert.assertEquals(1, provider.getDenniedTableStat("ALL_ALL_TABLES").getDenyCount()); + } +} diff --git a/src/test/java/com/alibaba/druid/bvt/filter/wall/WallDenyTableTest.java b/src/test/java/com/alibaba/druid/bvt/filter/wall/WallDenyTableTest.java index a3f253989d..985fd51cb8 100644 --- a/src/test/java/com/alibaba/druid/bvt/filter/wall/WallDenyTableTest.java +++ b/src/test/java/com/alibaba/druid/bvt/filter/wall/WallDenyTableTest.java @@ -28,11 +28,11 @@ import com.alibaba.druid.wall.spi.OracleWallProvider; public class WallDenyTableTest extends TestCase { public void testORACLE() throws Exception { - String sql = "SELECT F1, F2 FROM ALL_ALL_TABLES"; + String sql = "SELECT F1, F2 FROM SYS.ABC"; OracleWallProvider provider = new OracleWallProvider(); Assert.assertFalse(provider.checkValid(sql)); - Assert.assertEquals(1, provider.getDenniedTableStat("ALL_ALL_TABLES").getDenyCount()); + Assert.assertEquals(1, provider.getDenniedSchemaStat("SYS").getDenyCount()); } }