From 019f54ab8f260a30e913b8957c46008a1c32afe4 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E6=B8=A9=E5=B0=91?= Date: Thu, 22 Mar 2012 18:16:54 +0800 Subject: [PATCH] sqll wall --- .../druid/sql/ast/expr/SQLBinaryOperator.java | 23 ++++++ .../com/alibaba/druid/wall/WallConfig.java | 10 +++ .../druid/wall/spi/MySqlWallVisitor.java | 1 + .../druid/wall/spi/OracleWallVisitor.java | 2 +- .../druid/wall/spi/SQLServerWallVisitor.java | 1 + .../druid/wall/spi/WallVisitorUtils.java | 76 +++++++++++++++++-- .../bvt/filter/wall/IdentEqualsTest.java | 28 +++++++ .../bvt/filter/wall/IdentEqualsTest1.java | 28 +++++++ .../filter/wall/MustParameterizedTest.java | 28 +++++++ .../filter/wall/MustParameterizedTest1.java | 28 +++++++ 10 files changed, 216 insertions(+), 9 deletions(-) create mode 100644 src/test/java/com/alibaba/druid/bvt/filter/wall/IdentEqualsTest.java create mode 100644 src/test/java/com/alibaba/druid/bvt/filter/wall/IdentEqualsTest1.java create mode 100644 src/test/java/com/alibaba/druid/bvt/filter/wall/MustParameterizedTest.java create mode 100644 src/test/java/com/alibaba/druid/bvt/filter/wall/MustParameterizedTest1.java diff --git a/src/main/java/com/alibaba/druid/sql/ast/expr/SQLBinaryOperator.java b/src/main/java/com/alibaba/druid/sql/ast/expr/SQLBinaryOperator.java index ce4a2391d6..b371006492 100644 --- a/src/main/java/com/alibaba/druid/sql/ast/expr/SQLBinaryOperator.java +++ b/src/main/java/com/alibaba/druid/sql/ast/expr/SQLBinaryOperator.java @@ -92,4 +92,27 @@ public enum SQLBinaryOperator { this.name = name; this.priority = priority; } + + public boolean isRelational() { + switch (this) { + case Equality: + case Like: + case NotEqual: + case GreaterThan: + case GreaterThanOrEqual: + case LessThan: + case LessThanOrEqual: + case LessThanOrGreater: + case NotLike: + case NotLessThan: + case NotGreaterThan: + case RLike: + case NotRLike: + case RegExp: + case NotRegExp: + return true; + default: + return false; + } + } } diff --git a/src/main/java/com/alibaba/druid/wall/WallConfig.java b/src/main/java/com/alibaba/druid/wall/WallConfig.java index b1b559920b..045cfd31fb 100644 --- a/src/main/java/com/alibaba/druid/wall/WallConfig.java +++ b/src/main/java/com/alibaba/druid/wall/WallConfig.java @@ -39,6 +39,8 @@ public class WallConfig implements WallConfigMBean { private boolean objectCheck = true; private boolean variantCheck = true; + private boolean mustParameterized = false; + protected final Set permitFunctions = new HashSet(); protected final Set permitTables = new HashSet(); protected final Set permitSchemas = new HashSet(); @@ -283,6 +285,14 @@ public class WallConfig implements WallConfigMBean { return readOnlyTables; } + public boolean isMustParameterized() { + return mustParameterized; + } + + public void setMustParameterized(boolean mustParameterized) { + this.mustParameterized = mustParameterized; + } + public boolean isPermitObjects(String name) { if (!objectCheck) { return false; diff --git a/src/main/java/com/alibaba/druid/wall/spi/MySqlWallVisitor.java b/src/main/java/com/alibaba/druid/wall/spi/MySqlWallVisitor.java index 3f1bcc5b56..85069db23a 100644 --- a/src/main/java/com/alibaba/druid/wall/spi/MySqlWallVisitor.java +++ b/src/main/java/com/alibaba/druid/wall/spi/MySqlWallVisitor.java @@ -57,6 +57,7 @@ public class MySqlWallVisitor extends MySqlASTVisitorAdapter implements WallVisi } public boolean visit(SQLBinaryOpExpr x) { + WallVisitorUtils.check(this, x); return true; } 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 b133741d67..45769faf86 100644 --- a/src/main/java/com/alibaba/druid/wall/spi/OracleWallVisitor.java +++ b/src/main/java/com/alibaba/druid/wall/spi/OracleWallVisitor.java @@ -65,8 +65,8 @@ public class OracleWallVisitor extends OracleASTVIsitorAdapter implements WallVi return true; } - // executeQuery public boolean visit(SQLBinaryOpExpr x) { + WallVisitorUtils.check(this, x); return true; } 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 631b8e33a2..60e51ee3bb 100644 --- a/src/main/java/com/alibaba/druid/wall/spi/SQLServerWallVisitor.java +++ b/src/main/java/com/alibaba/druid/wall/spi/SQLServerWallVisitor.java @@ -84,6 +84,7 @@ public class SQLServerWallVisitor extends SQLServerASTVisitorAdapter implements // executeQuery public boolean visit(SQLBinaryOpExpr x) { + WallVisitorUtils.check(this, 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 b0c2996c07..5b4e436d6c 100644 --- a/src/main/java/com/alibaba/druid/wall/spi/WallVisitorUtils.java +++ b/src/main/java/com/alibaba/druid/wall/spi/WallVisitorUtils.java @@ -4,6 +4,7 @@ import java.io.BufferedReader; import java.io.IOException; import java.io.InputStream; import java.io.InputStreamReader; +import java.math.BigDecimal; import java.net.URL; import java.util.Enumeration; import java.util.Set; @@ -47,13 +48,23 @@ public class WallVisitorUtils { private final static Log LOG = LogFactory.getLog(WallVisitorUtils.class); + public static void check(WallVisitor visitor, SQLBinaryOpExpr x) { + if (x.getOperator().isRelational()) { + if (x.getLeft() instanceof SQLName && getValue(x.getRight()) != null) { + visitor.getViolations().add(new IllegalSQLObjectViolation(visitor.toSQL(x))); + } else if (x.getRight() instanceof SQLName && getValue(x.getLeft()) != null) { + visitor.getViolations().add(new IllegalSQLObjectViolation(visitor.toSQL(x))); + } + } + } + public static void check(WallVisitor visitor, SQLPropertyExpr x) { checkSchema(visitor, x.getOwner()); } public static void checkInsert(WallVisitor visitor, SQLInsertInto x) { checkReadOnly(visitor, x.getTableSource()); - + if (!visitor.getConfig().isInsertAllow()) { visitor.getViolations().add(new IllegalSQLObjectViolation(visitor.toSQL(x))); } @@ -63,7 +74,7 @@ public class WallVisitorUtils { if (x.getInto() != null) { checkReadOnly(visitor, x.getInto()); } - + if (!visitor.getConfig().isSelectIntoAllow() && x.getInto() != null) { addViolation(visitor, x); return; @@ -106,7 +117,7 @@ public class WallVisitorUtils { public static void checkDelete(WallVisitor visitor, SQLDeleteStatement x) { checkReadOnly(visitor, x.getExprTableSource()); - + if (!visitor.getConfig().isDeleteAllow()) { addViolation(visitor, x); return; @@ -128,7 +139,7 @@ public class WallVisitorUtils { if (tableNameExpr instanceof SQLName) { tableName = ((SQLName) tableNameExpr).getSimleName(); } - + if (tableName != null) { tableName = form(tableName); if (visitor.getConfig().getReadOnlyTables().contains(tableName)) { @@ -164,6 +175,33 @@ public class WallVisitorUtils { public static Object getValue(SQLBinaryOpExpr x) { x.getLeft().setParent(x); x.getRight().setParent(x); + + if (x.getLeft() instanceof SQLName && x.getRight() instanceof SQLName) { + if (x.getLeft().toString().equalsIgnoreCase(x.getRight().toString())) { + if (x.getOperator() == SQLBinaryOperator.Equality) { + return Boolean.TRUE; + } else if (x.getOperator() == SQLBinaryOperator.NotEqual) { + return Boolean.FALSE; + } + + switch (x.getOperator()) { + case Equality: + case Like: + return Boolean.TRUE; + case NotEqual: + case GreaterThan: + case GreaterThanOrEqual: + case LessThan: + case LessThanOrEqual: + case LessThanOrGreater: + case NotLike: + return Boolean.FALSE; + default: + break; + } + } + } + Object leftResult = getValue(x.getLeft()); Object rightResult = getValue(x.getRight()); @@ -283,9 +321,32 @@ public class WallVisitorUtils { if (x.getOperator() == SQLBinaryOperator.Concat) { return leftResult.toString() + rightResult.toString(); } + + if (x.getOperator() == SQLBinaryOperator.Add) { + if (leftResult == null || rightResult == null) { + return null; + } + + if (leftResult instanceof String || rightResult instanceof String) { + return leftResult.toString() + rightResult.toString(); + } + + + if (leftResult instanceof Number || rightResult instanceof Number) { + return add((Number) leftResult, (Number) rightResult); + } + } return null; } + + private static Number add(Number a, Number b) { + if (a instanceof BigDecimal) { + return ((BigDecimal) a).add(new BigDecimal(b.toString())); + } + + return a.longValue() + b.longValue(); + } public static Object getValue(SQLExpr x) { if (x instanceof SQLBinaryOpExpr) { @@ -449,13 +510,13 @@ public class WallVisitorUtils { if (visitor.getConfig().isPermitSchema(owner)) { addViolation(visitor, x); } - + if (visitor.getConfig().isPermitObjects(owner)) { addViolation(visitor, x); } } - - //if (ownerExpr instanceof SQLPropertyExpr) { + + // if (ownerExpr instanceof SQLPropertyExpr) { if (x instanceof SQLPropertyExpr) { checkSchema(visitor, ((SQLPropertyExpr) x).getOwner()); } @@ -464,7 +525,6 @@ public class WallVisitorUtils { public static void check(WallVisitor visitor, SQLExprTableSource x) { SQLExpr expr = x.getExpr(); - if (expr instanceof SQLPropertyExpr) { checkSchema(visitor, ((SQLPropertyExpr) expr).getOwner()); } diff --git a/src/test/java/com/alibaba/druid/bvt/filter/wall/IdentEqualsTest.java b/src/test/java/com/alibaba/druid/bvt/filter/wall/IdentEqualsTest.java new file mode 100644 index 0000000000..402e7a7421 --- /dev/null +++ b/src/test/java/com/alibaba/druid/bvt/filter/wall/IdentEqualsTest.java @@ -0,0 +1,28 @@ +package com.alibaba.druid.bvt.filter.wall; + +import junit.framework.TestCase; + +import org.junit.Assert; + +import com.alibaba.druid.wall.WallConfig; +import com.alibaba.druid.wall.WallUtils; + +public class IdentEqualsTest extends TestCase { + + private String sql = "select * from t where id = id"; + + private WallConfig config = new WallConfig(); + + protected void setUp() throws Exception { + + } + + 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/IdentEqualsTest1.java b/src/test/java/com/alibaba/druid/bvt/filter/wall/IdentEqualsTest1.java new file mode 100644 index 0000000000..dba9b69c04 --- /dev/null +++ b/src/test/java/com/alibaba/druid/bvt/filter/wall/IdentEqualsTest1.java @@ -0,0 +1,28 @@ +package com.alibaba.druid.bvt.filter.wall; + +import junit.framework.TestCase; + +import org.junit.Assert; + +import com.alibaba.druid.wall.WallConfig; +import com.alibaba.druid.wall.WallUtils; + +public class IdentEqualsTest1 extends TestCase { + + private String sql = "select * from t where not (id != id)"; + + private WallConfig config = new WallConfig(); + + protected void setUp() throws Exception { + + } + + 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/MustParameterizedTest.java b/src/test/java/com/alibaba/druid/bvt/filter/wall/MustParameterizedTest.java new file mode 100644 index 0000000000..edd0c76fc1 --- /dev/null +++ b/src/test/java/com/alibaba/druid/bvt/filter/wall/MustParameterizedTest.java @@ -0,0 +1,28 @@ +package com.alibaba.druid.bvt.filter.wall; + +import junit.framework.TestCase; + +import org.junit.Assert; + +import com.alibaba.druid.wall.WallConfig; +import com.alibaba.druid.wall.WallUtils; + +public class MustParameterizedTest extends TestCase { + + private String sql = "select * from t where id = 3"; + + private WallConfig config = new WallConfig(); + + protected void setUp() throws Exception { + config.setMustParameterized(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/MustParameterizedTest1.java b/src/test/java/com/alibaba/druid/bvt/filter/wall/MustParameterizedTest1.java new file mode 100644 index 0000000000..156edd321a --- /dev/null +++ b/src/test/java/com/alibaba/druid/bvt/filter/wall/MustParameterizedTest1.java @@ -0,0 +1,28 @@ +package com.alibaba.druid.bvt.filter.wall; + +import junit.framework.TestCase; + +import org.junit.Assert; + +import com.alibaba.druid.wall.WallConfig; +import com.alibaba.druid.wall.WallUtils; + +public class MustParameterizedTest1 extends TestCase { + + private String sql = "select * from t where id = 3 + 5"; + + private WallConfig config = new WallConfig(); + + protected void setUp() throws Exception { + config.setMustParameterized(true); + } + + public void testMySql() throws Exception { + Assert.assertFalse(WallUtils.isValidateMySql(sql, config)); + } + + public void testORACLE() throws Exception { + + Assert.assertFalse(WallUtils.isValidateOracle(sql, config)); + } +}