From 56d3a85461d35d68b495d81012d86c37b4aeb033 Mon Sep 17 00:00:00 2001 From: wenshao Date: Wed, 28 Aug 2013 13:56:56 +0800 Subject: [PATCH 1/3] =?UTF-8?q?=E9=81=BF=E5=85=8D=E5=88=9B=E5=BB=BAsession?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../druid/support/http/ResourceSerlvet.java | 21 +++++++++++++------ 1 file changed, 15 insertions(+), 6 deletions(-) diff --git a/src/main/java/com/alibaba/druid/support/http/ResourceSerlvet.java b/src/main/java/com/alibaba/druid/support/http/ResourceSerlvet.java index 7db5c31a99..64652d6837 100644 --- a/src/main/java/com/alibaba/druid/support/http/ResourceSerlvet.java +++ b/src/main/java/com/alibaba/druid/support/http/ResourceSerlvet.java @@ -179,7 +179,6 @@ public abstract class ResourceSerlvet extends HttpServlet { } public void service(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException { - HttpSession session = request.getSession(); String contextPath = request.getContextPath(); String servletPath = request.getServletPath(); String requestURI = request.getRequestURI(); @@ -210,9 +209,12 @@ public abstract class ResourceSerlvet extends HttpServlet { return; } - if (isRequireAuth() - && session.getAttribute(SESSION_USER_KEY) == null - && !("/login.html".equals(path) || path.startsWith("/css") || path.startsWith("/js") || path.startsWith("/img"))) { + if (isRequireAuth() // + && !ContainsUser(request)// + && !("/login.html".equals(path) // + || path.startsWith("/css")// + || path.startsWith("/js") // + || path.startsWith("/img"))) { if (contextPath == null || contextPath.equals("") || contextPath.equals("/")) { response.sendRedirect("/druid/login.html"); } else { @@ -247,7 +249,14 @@ public abstract class ResourceSerlvet extends HttpServlet { // find file in resources path returnResourceFile(path, uri, response); } - + + public boolean ContainsUser(HttpServletRequest request) { + HttpSession session = request.getSession(false); + if (session == null) { + return false; + } + return session.getAttribute(SESSION_USER_KEY) != null; + } public boolean isRequireAuth() { return this.username != null; @@ -257,6 +266,6 @@ public abstract class ResourceSerlvet extends HttpServlet { String remoteAddress = request.getRemoteAddr(); return isPermittedRequest(remoteAddress); } - + protected abstract String process(String url); } From a20d637128f017d98b25a8943669380dca77dab0 Mon Sep 17 00:00:00 2001 From: wenshao Date: Wed, 28 Aug 2013 13:57:40 +0800 Subject: [PATCH 2/3] =?UTF-8?q?=E5=A2=9E=E5=BC=BA=E5=AF=B9hints=E7=9A=84?= =?UTF-8?q?=E9=98=B2=E5=BE=A1?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../druid/wall/spi/MySqlWallVisitor.java | 1019 +++++++++-------- .../bvt/filter/wall/MySqlWallTest134.java | 33 + .../bvt/filter/wall/MySqlWallTest135.java | 33 + .../bvt/filter/wall/MySqlWallTest136.java | 33 + 4 files changed, 617 insertions(+), 501 deletions(-) create mode 100644 src/test/java/com/alibaba/druid/bvt/filter/wall/MySqlWallTest134.java create mode 100644 src/test/java/com/alibaba/druid/bvt/filter/wall/MySqlWallTest135.java create mode 100644 src/test/java/com/alibaba/druid/bvt/filter/wall/MySqlWallTest136.java 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 54808551aa..92cb6d017e 100644 --- a/src/main/java/com/alibaba/druid/wall/spi/MySqlWallVisitor.java +++ b/src/main/java/com/alibaba/druid/wall/spi/MySqlWallVisitor.java @@ -1,501 +1,518 @@ -/* - * 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.wall.spi; - -import java.util.ArrayList; -import java.util.List; - -import com.alibaba.druid.sql.SQLUtils; -import com.alibaba.druid.sql.ast.SQLCommentHint; -import com.alibaba.druid.sql.ast.SQLName; -import com.alibaba.druid.sql.ast.SQLObject; -import com.alibaba.druid.sql.ast.expr.SQLBinaryOpExpr; -import com.alibaba.druid.sql.ast.expr.SQLInListExpr; -import com.alibaba.druid.sql.ast.expr.SQLMethodInvokeExpr; -import com.alibaba.druid.sql.ast.expr.SQLNumericLiteralExpr; -import com.alibaba.druid.sql.ast.expr.SQLPropertyExpr; -import com.alibaba.druid.sql.ast.expr.SQLVariantRefExpr; -import com.alibaba.druid.sql.ast.statement.SQLAlterTableStatement; -import com.alibaba.druid.sql.ast.statement.SQLAssignItem; -import com.alibaba.druid.sql.ast.statement.SQLCallStatement; -import com.alibaba.druid.sql.ast.statement.SQLCreateTableStatement; -import com.alibaba.druid.sql.ast.statement.SQLCreateTriggerStatement; -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.SQLSelectGroupByClause; -import com.alibaba.druid.sql.ast.statement.SQLSelectItem; -import com.alibaba.druid.sql.ast.statement.SQLSelectQueryBlock; -import com.alibaba.druid.sql.ast.statement.SQLSelectStatement; -import com.alibaba.druid.sql.ast.statement.SQLSetStatement; -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.MySqlAlterTableStatement; -import com.alibaba.druid.sql.dialect.mysql.ast.statement.MySqlCreateTableStatement; -import com.alibaba.druid.sql.dialect.mysql.ast.statement.MySqlDeleteStatement; -import com.alibaba.druid.sql.dialect.mysql.ast.statement.MySqlInsertStatement; -import com.alibaba.druid.sql.dialect.mysql.ast.statement.MySqlReplaceStatement; -import com.alibaba.druid.sql.dialect.mysql.ast.statement.MySqlSelectGroupBy; -import com.alibaba.druid.sql.dialect.mysql.ast.statement.MySqlSelectQueryBlock; -import com.alibaba.druid.sql.dialect.mysql.ast.statement.MySqlSelectQueryBlock.Limit; -import com.alibaba.druid.sql.dialect.mysql.ast.statement.MySqlShowCreateTableStatement; -import com.alibaba.druid.sql.dialect.mysql.ast.statement.MySqlUnionQuery; -import com.alibaba.druid.sql.dialect.mysql.ast.statement.MySqlUpdateStatement; -import com.alibaba.druid.sql.dialect.mysql.visitor.MySqlASTVisitor; -import com.alibaba.druid.sql.dialect.mysql.visitor.MySqlASTVisitorAdapter; -import com.alibaba.druid.util.JdbcConstants; -import com.alibaba.druid.wall.Violation; -import com.alibaba.druid.wall.WallConfig; -import com.alibaba.druid.wall.WallContext; -import com.alibaba.druid.wall.WallProvider; -import com.alibaba.druid.wall.WallSqlTableStat; -import com.alibaba.druid.wall.WallVisitor; -import com.alibaba.druid.wall.violation.ErrorCode; -import com.alibaba.druid.wall.violation.IllegalSQLObjectViolation; - -public class MySqlWallVisitor extends MySqlASTVisitorAdapter implements WallVisitor, MySqlASTVisitor { - - private final WallConfig config; - private final WallProvider provider; - private final List violations = new ArrayList(); - private boolean sqlModified = false; - - public MySqlWallVisitor(WallProvider provider){ - this.config = provider.getConfig(); - this.provider = provider; - } - - @Override - public String getDbType() { - return JdbcConstants.MYSQL; - } - - @Override - public boolean isSqlModified() { - return sqlModified; - } - - @Override - public void setSqlModified(boolean sqlModified) { - this.sqlModified = sqlModified; - } - - @Override - public WallProvider getProvider() { - return provider; - } - - @Override - public WallConfig getConfig() { - return config; - } - - @Override - public void addViolation(Violation violation) { - this.violations.add(violation); - } - - @Override - public List getViolations() { - return violations; - } - - public boolean visit(SQLInListExpr x) { - WallVisitorUtils.check(this, x); - return true; - } - - public boolean visit(SQLBinaryOpExpr x) { - WallVisitorUtils.check(this, x); - return true; - } - - @Override - public boolean visit(SQLSelectQueryBlock x) { - WallVisitorUtils.checkSelelct(this, x); - - return true; - } - - @Override - public boolean visit(MySqlSelectQueryBlock x) { - WallVisitorUtils.checkSelelct(this, x); - return true; - } - - public boolean visit(SQLSelectGroupByClause x) { - WallVisitorUtils.checkHaving(this, x.getHaving()); - return true; - } - - public boolean visit(MySqlSelectGroupBy x) { - WallVisitorUtils.checkHaving(this, x.getHaving()); - return true; - } - - @Override - public boolean visit(MySqlDeleteStatement x) { - WallVisitorUtils.checkReadOnly(this, x.getFrom()); - - return visit((SQLDeleteStatement) x); - } - - @Override - public boolean visit(SQLDeleteStatement x) { - WallVisitorUtils.checkDelete(this, x); - return true; - } - - @Override - public boolean visit(MySqlUpdateStatement x) { - return visit((SQLUpdateStatement) x); - } - - @Override - public boolean visit(SQLUpdateStatement x) { - WallVisitorUtils.initWallTopStatementContext(); - WallVisitorUtils.checkUpdate(this, x); - return true; - } - - @Override - public void endVisit(SQLUpdateStatement x) { - WallVisitorUtils.clearWallTopStatementContext(); - } - - @Override - public boolean visit(MySqlInsertStatement x) { - return visit((SQLInsertStatement) x); - } - - @Override - public boolean visit(SQLInsertStatement x) { - WallVisitorUtils.initWallTopStatementContext(); - WallVisitorUtils.checkInsert(this, x); - return true; - } - - @Override - public void endVisit(SQLInsertStatement x) { - WallVisitorUtils.clearWallTopStatementContext(); - } - - @Override - public boolean visit(SQLSelectStatement x) { - if (!config.isSelelctAllow()) { - this.getViolations().add(new IllegalSQLObjectViolation(ErrorCode.SELECT_NOT_ALLOW, "select not allow", - this.toSQL(x))); - return false; - } - - WallVisitorUtils.initWallTopStatementContext(); - return true; - } - - @Override - public void endVisit(SQLSelectStatement x) { - WallVisitorUtils.clearWallTopStatementContext(); - } - - @Override - public boolean visit(Limit x) { - if (x.getRowCount() instanceof SQLNumericLiteralExpr) { - WallContext context = WallContext.current(); - - int rowCount = ((SQLNumericLiteralExpr) x.getRowCount()).getNumber().intValue(); - if (rowCount == 0) { - if (context != null) { - context.incrementWarnnings(); - } - - if (!provider.getConfig().isLimitZeroAllow()) { - this.getViolations().add(new IllegalSQLObjectViolation(ErrorCode.LIMIT_ZERO, "limit row 0", - this.toSQL(x))); - } - } - } - return true; - } - - public boolean visit(SQLPropertyExpr x) { - if (x.getOwner() instanceof SQLVariantRefExpr) { - SQLVariantRefExpr varExpr = (SQLVariantRefExpr) x.getOwner(); - SQLObject parent = x.getParent(); - String varName = varExpr.getName(); - if (varName.equalsIgnoreCase("@@session") || varName.equalsIgnoreCase("@@global")) { - if (!(parent instanceof SQLSelectItem) && !(parent instanceof SQLAssignItem)) { - violations.add(new IllegalSQLObjectViolation(ErrorCode.VARIANT_DENY, - "variable in condition not allow", toSQL(x))); - return false; - } - - if (!checkVar(x.getParent(), x.getName())) { - boolean isTop = WallVisitorUtils.isTopNoneFromSelect(this, x); - if (!isTop) { - boolean allow = true; - if (WallVisitorUtils.isWhereOrHaving(x) && isDeny(varName)) { - allow = false; - } - - if (!allow) { - violations.add(new IllegalSQLObjectViolation(ErrorCode.VARIANT_DENY, - "variable not allow : " + x.getName(), - toSQL(x))); - } - } - } - return false; - } - } - - WallVisitorUtils.check(this, x); - return true; - } - - public boolean checkVar(SQLObject parent, String varName) { - if (varName == null) { - return false; - } - - if (varName.equals("?")) { - return true; - } - - if (!config.isVariantCheck()) { - return true; - } - - if (varName.startsWith("@@")) { - if (!(parent instanceof SQLSelectItem) && !(parent instanceof SQLAssignItem)) { - return false; - } - - varName = varName.substring(2); - } - - if (config.getPermitVariants().contains(varName)) { - return true; - } - - return false; - } - - public boolean isDeny(String varName) { - if (varName.startsWith("@@")) { - varName = varName.substring(2); - } - - return config.getDenyVariants().contains(varName); - } - - public boolean visit(SQLVariantRefExpr x) { - String varName = x.getName(); - if (varName == null) { - return false; - } - - if (varName.startsWith("@@") && !checkVar(x.getParent(), x.getName())) { - boolean isTop = WallVisitorUtils.isTopNoneFromSelect(this, x); - if (!isTop) { - boolean allow = true; - if (WallVisitorUtils.isWhereOrHaving(x) && isDeny(varName)) { - allow = false; - } - - if (!allow) { - violations.add(new IllegalSQLObjectViolation(ErrorCode.VARIANT_DENY, "variable not allow : " - + x.getName(), toSQL(x))); - } - } - } - - return false; - } - - @Override - public boolean visit(SQLMethodInvokeExpr x) { - WallVisitorUtils.checkFunction(this, x); - - return true; - } - - public boolean visit(SQLExprTableSource x) { - WallVisitorUtils.check(this, x); - - if (x.getExpr() instanceof SQLName) { - return false; - } - - return true; - } - - @Override - public boolean visit(MySqlOutFileExpr x) { - if (!config.isSelectIntoOutfileAllow()) { - violations.add(new IllegalSQLObjectViolation(ErrorCode.INTO_OUTFILE, "into out file not allow", toSQL(x))); - } - - return true; - } - - @Override - public boolean visit(SQLUnionQuery x) { - WallVisitorUtils.checkUnion(this, x); - - return true; - } - - @Override - public boolean visit(MySqlUnionQuery x) { - WallVisitorUtils.checkUnion(this, x); - - return true; - } - - @Override - public String toSQL(SQLObject obj) { - return SQLUtils.toMySqlString(obj); - } - - @Override - public boolean isDenyTable(String name) { - if (!config.isTableCheck()) { - return false; - } - - return !this.provider.checkDenyTable(name); - } - - public void preVisit(SQLObject x) { - WallVisitorUtils.preVisitCheck(this, x); - } - - @Override - public boolean visit(SQLSelectItem x) { - WallVisitorUtils.check(this, x); - return true; - } - - @Override - public boolean visit(SQLCreateTableStatement x) { - WallVisitorUtils.check(this, x); - return true; - } - - @Override - public boolean visit(MySqlCreateTableStatement x) { - WallVisitorUtils.check(this, x); - return true; - } - - public boolean visit(SQLAlterTableStatement x) { - WallVisitorUtils.check(this, x); - return true; - } - - @Override - public boolean visit(MySqlAlterTableStatement x) { - WallVisitorUtils.check(this, x); - return true; - } - - public boolean visit(SQLDropTableStatement x) { - WallVisitorUtils.check(this, x); - return true; - } - - @Override - public boolean visit(SQLSetStatement x) { - return false; - } - - @Override - public boolean visit(MySqlReplaceStatement x) { - return true; - } - - @Override - public boolean visit(SQLCallStatement x) { - return false; - } - - @Override - public boolean visit(SQLCommentHint x) { - String text = x.getText(); - text = text.trim(); - if (text.startsWith("!")) { - text = text.substring(1); - } - - if (text.length() == 0) { - return true; - } - - if (Character.isDigit(text.charAt(0))) { - addViolation(new IllegalSQLObjectViolation(ErrorCode.EVIL_HINTS, "evil hints", SQLUtils.toMySqlString(x))); - } - - text = text.toLowerCase(); - - if (text.indexOf(';') != -1 // - || text.indexOf("or") != -1 // - || text.indexOf("and") != -1 // - || text.indexOf("union") != -1 // - - || text.indexOf("select") != -1 // - || text.indexOf("delete") != -1 // - || text.indexOf("insert") != -1 // - || text.indexOf("update") != -1 // - - || text.indexOf("create") != -1 // - || text.indexOf("drop") != -1 // - || text.indexOf("alter") != -1 // - || text.indexOf("truncate") != -1 // - - || text.indexOf("information_schema") != -1 // - || text.indexOf("mysql") != -1 // - || text.indexOf("performance_schema") != -1 // - - || text.indexOf("sleep") != -1 // - || text.indexOf("benchmark") != -1 // - || text.indexOf("load_file") != -1 // - ) { - addViolation(new IllegalSQLObjectViolation(ErrorCode.EVIL_HINTS, "evil hints", SQLUtils.toMySqlString(x))); - } - - return true; - } - - @Override - public boolean visit(MySqlShowCreateTableStatement x) { - String tableName = ((SQLName) x.getName()).getSimleName(); - WallContext context = WallContext.current(); - if (context != null) { - WallSqlTableStat tableStat = context.getTableStat(tableName); - if (tableStat != null) { - tableStat.incrementShowCount(); - } - } - return false; - } - - @Override - public boolean visit(SQLCreateTriggerStatement x) { - return false; - } -} +/* + * 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.wall.spi; + +import java.util.ArrayList; +import java.util.List; + +import com.alibaba.druid.sql.SQLUtils; +import com.alibaba.druid.sql.ast.SQLCommentHint; +import com.alibaba.druid.sql.ast.SQLName; +import com.alibaba.druid.sql.ast.SQLObject; +import com.alibaba.druid.sql.ast.expr.SQLBinaryOpExpr; +import com.alibaba.druid.sql.ast.expr.SQLInListExpr; +import com.alibaba.druid.sql.ast.expr.SQLMethodInvokeExpr; +import com.alibaba.druid.sql.ast.expr.SQLNumericLiteralExpr; +import com.alibaba.druid.sql.ast.expr.SQLPropertyExpr; +import com.alibaba.druid.sql.ast.expr.SQLVariantRefExpr; +import com.alibaba.druid.sql.ast.statement.SQLAlterTableStatement; +import com.alibaba.druid.sql.ast.statement.SQLAssignItem; +import com.alibaba.druid.sql.ast.statement.SQLCallStatement; +import com.alibaba.druid.sql.ast.statement.SQLCreateTableStatement; +import com.alibaba.druid.sql.ast.statement.SQLCreateTriggerStatement; +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.SQLSelectGroupByClause; +import com.alibaba.druid.sql.ast.statement.SQLSelectItem; +import com.alibaba.druid.sql.ast.statement.SQLSelectQueryBlock; +import com.alibaba.druid.sql.ast.statement.SQLSelectStatement; +import com.alibaba.druid.sql.ast.statement.SQLSetStatement; +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.MySqlAlterTableStatement; +import com.alibaba.druid.sql.dialect.mysql.ast.statement.MySqlCreateTableStatement; +import com.alibaba.druid.sql.dialect.mysql.ast.statement.MySqlDeleteStatement; +import com.alibaba.druid.sql.dialect.mysql.ast.statement.MySqlInsertStatement; +import com.alibaba.druid.sql.dialect.mysql.ast.statement.MySqlReplaceStatement; +import com.alibaba.druid.sql.dialect.mysql.ast.statement.MySqlSelectGroupBy; +import com.alibaba.druid.sql.dialect.mysql.ast.statement.MySqlSelectQueryBlock; +import com.alibaba.druid.sql.dialect.mysql.ast.statement.MySqlSelectQueryBlock.Limit; +import com.alibaba.druid.sql.dialect.mysql.ast.statement.MySqlShowCreateTableStatement; +import com.alibaba.druid.sql.dialect.mysql.ast.statement.MySqlUnionQuery; +import com.alibaba.druid.sql.dialect.mysql.ast.statement.MySqlUpdateStatement; +import com.alibaba.druid.sql.dialect.mysql.visitor.MySqlASTVisitor; +import com.alibaba.druid.sql.dialect.mysql.visitor.MySqlASTVisitorAdapter; +import com.alibaba.druid.util.JdbcConstants; +import com.alibaba.druid.wall.Violation; +import com.alibaba.druid.wall.WallConfig; +import com.alibaba.druid.wall.WallContext; +import com.alibaba.druid.wall.WallProvider; +import com.alibaba.druid.wall.WallSqlTableStat; +import com.alibaba.druid.wall.WallVisitor; +import com.alibaba.druid.wall.violation.ErrorCode; +import com.alibaba.druid.wall.violation.IllegalSQLObjectViolation; + +public class MySqlWallVisitor extends MySqlASTVisitorAdapter implements WallVisitor, MySqlASTVisitor { + + private final WallConfig config; + private final WallProvider provider; + private final List violations = new ArrayList(); + private boolean sqlModified = false; + + public MySqlWallVisitor(WallProvider provider){ + this.config = provider.getConfig(); + this.provider = provider; + } + + @Override + public String getDbType() { + return JdbcConstants.MYSQL; + } + + @Override + public boolean isSqlModified() { + return sqlModified; + } + + @Override + public void setSqlModified(boolean sqlModified) { + this.sqlModified = sqlModified; + } + + @Override + public WallProvider getProvider() { + return provider; + } + + @Override + public WallConfig getConfig() { + return config; + } + + @Override + public void addViolation(Violation violation) { + this.violations.add(violation); + } + + @Override + public List getViolations() { + return violations; + } + + public boolean visit(SQLInListExpr x) { + WallVisitorUtils.check(this, x); + return true; + } + + public boolean visit(SQLBinaryOpExpr x) { + WallVisitorUtils.check(this, x); + return true; + } + + @Override + public boolean visit(SQLSelectQueryBlock x) { + WallVisitorUtils.checkSelelct(this, x); + + return true; + } + + @Override + public boolean visit(MySqlSelectQueryBlock x) { + WallVisitorUtils.checkSelelct(this, x); + return true; + } + + public boolean visit(SQLSelectGroupByClause x) { + WallVisitorUtils.checkHaving(this, x.getHaving()); + return true; + } + + public boolean visit(MySqlSelectGroupBy x) { + WallVisitorUtils.checkHaving(this, x.getHaving()); + return true; + } + + @Override + public boolean visit(MySqlDeleteStatement x) { + WallVisitorUtils.checkReadOnly(this, x.getFrom()); + + return visit((SQLDeleteStatement) x); + } + + @Override + public boolean visit(SQLDeleteStatement x) { + WallVisitorUtils.checkDelete(this, x); + return true; + } + + @Override + public boolean visit(MySqlUpdateStatement x) { + return visit((SQLUpdateStatement) x); + } + + @Override + public boolean visit(SQLUpdateStatement x) { + WallVisitorUtils.initWallTopStatementContext(); + WallVisitorUtils.checkUpdate(this, x); + return true; + } + + @Override + public void endVisit(SQLUpdateStatement x) { + WallVisitorUtils.clearWallTopStatementContext(); + } + + @Override + public boolean visit(MySqlInsertStatement x) { + return visit((SQLInsertStatement) x); + } + + @Override + public boolean visit(SQLInsertStatement x) { + WallVisitorUtils.initWallTopStatementContext(); + WallVisitorUtils.checkInsert(this, x); + return true; + } + + @Override + public void endVisit(SQLInsertStatement x) { + WallVisitorUtils.clearWallTopStatementContext(); + } + + @Override + public boolean visit(SQLSelectStatement x) { + if (!config.isSelelctAllow()) { + this.getViolations().add(new IllegalSQLObjectViolation(ErrorCode.SELECT_NOT_ALLOW, "select not allow", + this.toSQL(x))); + return false; + } + + WallVisitorUtils.initWallTopStatementContext(); + return true; + } + + @Override + public void endVisit(SQLSelectStatement x) { + WallVisitorUtils.clearWallTopStatementContext(); + } + + @Override + public boolean visit(Limit x) { + if (x.getRowCount() instanceof SQLNumericLiteralExpr) { + WallContext context = WallContext.current(); + + int rowCount = ((SQLNumericLiteralExpr) x.getRowCount()).getNumber().intValue(); + if (rowCount == 0) { + if (context != null) { + context.incrementWarnnings(); + } + + if (!provider.getConfig().isLimitZeroAllow()) { + this.getViolations().add(new IllegalSQLObjectViolation(ErrorCode.LIMIT_ZERO, "limit row 0", + this.toSQL(x))); + } + } + } + return true; + } + + public boolean visit(SQLPropertyExpr x) { + if (x.getOwner() instanceof SQLVariantRefExpr) { + SQLVariantRefExpr varExpr = (SQLVariantRefExpr) x.getOwner(); + SQLObject parent = x.getParent(); + String varName = varExpr.getName(); + if (varName.equalsIgnoreCase("@@session") || varName.equalsIgnoreCase("@@global")) { + if (!(parent instanceof SQLSelectItem) && !(parent instanceof SQLAssignItem)) { + violations.add(new IllegalSQLObjectViolation(ErrorCode.VARIANT_DENY, + "variable in condition not allow", toSQL(x))); + return false; + } + + if (!checkVar(x.getParent(), x.getName())) { + boolean isTop = WallVisitorUtils.isTopNoneFromSelect(this, x); + if (!isTop) { + boolean allow = true; + if (WallVisitorUtils.isWhereOrHaving(x) && isDeny(varName)) { + allow = false; + } + + if (!allow) { + violations.add(new IllegalSQLObjectViolation(ErrorCode.VARIANT_DENY, + "variable not allow : " + x.getName(), + toSQL(x))); + } + } + } + return false; + } + } + + WallVisitorUtils.check(this, x); + return true; + } + + public boolean checkVar(SQLObject parent, String varName) { + if (varName == null) { + return false; + } + + if (varName.equals("?")) { + return true; + } + + if (!config.isVariantCheck()) { + return true; + } + + if (varName.startsWith("@@")) { + if (!(parent instanceof SQLSelectItem) && !(parent instanceof SQLAssignItem)) { + return false; + } + + varName = varName.substring(2); + } + + if (config.getPermitVariants().contains(varName)) { + return true; + } + + return false; + } + + public boolean isDeny(String varName) { + if (varName.startsWith("@@")) { + varName = varName.substring(2); + } + + return config.getDenyVariants().contains(varName); + } + + public boolean visit(SQLVariantRefExpr x) { + String varName = x.getName(); + if (varName == null) { + return false; + } + + if (varName.startsWith("@@") && !checkVar(x.getParent(), x.getName())) { + boolean isTop = WallVisitorUtils.isTopNoneFromSelect(this, x); + if (!isTop) { + boolean allow = true; + if (WallVisitorUtils.isWhereOrHaving(x) && isDeny(varName)) { + allow = false; + } + + if (!allow) { + violations.add(new IllegalSQLObjectViolation(ErrorCode.VARIANT_DENY, "variable not allow : " + + x.getName(), toSQL(x))); + } + } + } + + return false; + } + + @Override + public boolean visit(SQLMethodInvokeExpr x) { + WallVisitorUtils.checkFunction(this, x); + + return true; + } + + public boolean visit(SQLExprTableSource x) { + WallVisitorUtils.check(this, x); + + if (x.getExpr() instanceof SQLName) { + return false; + } + + return true; + } + + @Override + public boolean visit(MySqlOutFileExpr x) { + if (!config.isSelectIntoOutfileAllow()) { + violations.add(new IllegalSQLObjectViolation(ErrorCode.INTO_OUTFILE, "into out file not allow", toSQL(x))); + } + + return true; + } + + @Override + public boolean visit(SQLUnionQuery x) { + WallVisitorUtils.checkUnion(this, x); + + return true; + } + + @Override + public boolean visit(MySqlUnionQuery x) { + WallVisitorUtils.checkUnion(this, x); + + return true; + } + + @Override + public String toSQL(SQLObject obj) { + return SQLUtils.toMySqlString(obj); + } + + @Override + public boolean isDenyTable(String name) { + if (!config.isTableCheck()) { + return false; + } + + return !this.provider.checkDenyTable(name); + } + + public void preVisit(SQLObject x) { + WallVisitorUtils.preVisitCheck(this, x); + } + + @Override + public boolean visit(SQLSelectItem x) { + WallVisitorUtils.check(this, x); + return true; + } + + @Override + public boolean visit(SQLCreateTableStatement x) { + WallVisitorUtils.check(this, x); + return true; + } + + @Override + public boolean visit(MySqlCreateTableStatement x) { + WallVisitorUtils.check(this, x); + return true; + } + + public boolean visit(SQLAlterTableStatement x) { + WallVisitorUtils.check(this, x); + return true; + } + + @Override + public boolean visit(MySqlAlterTableStatement x) { + WallVisitorUtils.check(this, x); + return true; + } + + public boolean visit(SQLDropTableStatement x) { + WallVisitorUtils.check(this, x); + return true; + } + + @Override + public boolean visit(SQLSetStatement x) { + return false; + } + + @Override + public boolean visit(MySqlReplaceStatement x) { + return true; + } + + @Override + public boolean visit(SQLCallStatement x) { + return false; + } + + @Override + public boolean visit(SQLCommentHint x) { + String text = x.getText(); + text = text.trim(); + if (text.startsWith("!")) { + text = text.substring(1); + } + + if (text.length() == 0) { + return true; + } + + if (Character.isDigit(text.charAt(0))) { + addViolation(new IllegalSQLObjectViolation(ErrorCode.EVIL_HINTS, "evil hints", SQLUtils.toMySqlString(x))); + } + + text = text.toLowerCase(); + + for (int i = 0; i < text.length(); ++i) { + char ch = text.charAt(i); + switch (ch) { + case ';': + case '>': + case '=': + case '<': + case '&': + case '|': + case '^': + case '\n': + addViolation(new IllegalSQLObjectViolation(ErrorCode.EVIL_HINTS, "evil hints", SQLUtils.toMySqlString(x))); + default: + break; + } + } + + if (text.indexOf("or") != -1 // + || text.indexOf("and") != -1 // + || text.indexOf("union") != -1 // + + || text.indexOf("select") != -1 // + || text.indexOf("delete") != -1 // + || text.indexOf("insert") != -1 // + || text.indexOf("update") != -1 // + || text.indexOf("into") != -1 // + + || text.indexOf("create") != -1 // + || text.indexOf("drop") != -1 // + || text.indexOf("alter") != -1 // + || text.indexOf("truncate") != -1 // + + || text.indexOf("information_schema") != -1 // + || text.indexOf("mysql") != -1 // + || text.indexOf("performance_schema") != -1 // + + || text.indexOf("sleep") != -1 // + || text.indexOf("benchmark") != -1 // + || text.indexOf("load_file") != -1 // + ) { + addViolation(new IllegalSQLObjectViolation(ErrorCode.EVIL_HINTS, "evil hints", SQLUtils.toMySqlString(x))); + } + + return true; + } + + @Override + public boolean visit(MySqlShowCreateTableStatement x) { + String tableName = ((SQLName) x.getName()).getSimleName(); + WallContext context = WallContext.current(); + if (context != null) { + WallSqlTableStat tableStat = context.getTableStat(tableName); + if (tableStat != null) { + tableStat.incrementShowCount(); + } + } + return false; + } + + @Override + public boolean visit(SQLCreateTriggerStatement x) { + return false; + } +} diff --git a/src/test/java/com/alibaba/druid/bvt/filter/wall/MySqlWallTest134.java b/src/test/java/com/alibaba/druid/bvt/filter/wall/MySqlWallTest134.java new file mode 100644 index 0000000000..1ee91281f8 --- /dev/null +++ b/src/test/java/com/alibaba/druid/bvt/filter/wall/MySqlWallTest134.java @@ -0,0 +1,33 @@ +/* + * 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 MySqlWallTest134 extends TestCase { + + public void test_false() throws Exception { + WallProvider provider = new MySqlWallProvider(); + + Assert.assertFalse(provider.checkValid("SELECT 1 FROM dual WHERE 1 = '1'''''''''''''UNION SELECT '2';")); + } + +} diff --git a/src/test/java/com/alibaba/druid/bvt/filter/wall/MySqlWallTest135.java b/src/test/java/com/alibaba/druid/bvt/filter/wall/MySqlWallTest135.java new file mode 100644 index 0000000000..ca6a66a011 --- /dev/null +++ b/src/test/java/com/alibaba/druid/bvt/filter/wall/MySqlWallTest135.java @@ -0,0 +1,33 @@ +/* + * 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 MySqlWallTest135 extends TestCase { + + public void test_false() throws Exception { + WallProvider provider = new MySqlWallProvider(); + + Assert.assertFalse(provider.checkValid("SELECT * FROM Users WHERE id = '1' AND MID(VERSION(),1,1) = '5';")); + } + +} diff --git a/src/test/java/com/alibaba/druid/bvt/filter/wall/MySqlWallTest136.java b/src/test/java/com/alibaba/druid/bvt/filter/wall/MySqlWallTest136.java new file mode 100644 index 0000000000..7b1eb148ea --- /dev/null +++ b/src/test/java/com/alibaba/druid/bvt/filter/wall/MySqlWallTest136.java @@ -0,0 +1,33 @@ +/* + * 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 MySqlWallTest136 extends TestCase { + + public void test_false() throws Exception { + WallProvider provider = new MySqlWallProvider(); + + Assert.assertFalse(provider.checkValid("SELECT * FROM Users WHERE id = '1' AND MID(@@VERSION,1,1) = '5';")); + } + +} From 670c376feb9bbd373e1559ede9119b44674ecd98 Mon Sep 17 00:00:00 2001 From: wenshao Date: Wed, 28 Aug 2013 16:47:58 +0800 Subject: [PATCH 3/3] improve sql wall --- .../sql/dialect/mysql/parser/MySqlLexer.java | 47 ++++++----- .../druid/sql/parser/SQLExprParser.java | 2 +- .../sql/visitor/SQLEvalVisitorUtils.java | 20 +++-- .../com/alibaba/druid/wall/WallConfig.java | 10 +++ .../druid/wall/spi/WallVisitorUtils.java | 42 +++++----- .../bvt/filter/wall/MySqlWallTest137.java | 35 ++++++++ .../bvt/filter/wall/MySqlWallTest138.java | 43 ++++++++++ .../bvt/filter/wall/MySqlWallTest75.java | 8 +- .../test/wall/MySqlResourceWallTest.java | 79 +++++++++++++++++++ 9 files changed, 233 insertions(+), 53 deletions(-) create mode 100644 src/test/java/com/alibaba/druid/bvt/filter/wall/MySqlWallTest137.java create mode 100644 src/test/java/com/alibaba/druid/bvt/filter/wall/MySqlWallTest138.java create mode 100644 src/test/java/com/alibaba/druid/test/wall/MySqlResourceWallTest.java diff --git a/src/main/java/com/alibaba/druid/sql/dialect/mysql/parser/MySqlLexer.java b/src/main/java/com/alibaba/druid/sql/dialect/mysql/parser/MySqlLexer.java index d481bc9ae3..c3e35fc519 100644 --- a/src/main/java/com/alibaba/druid/sql/dialect/mysql/parser/MySqlLexer.java +++ b/src/main/java/com/alibaba/druid/sql/dialect/mysql/parser/MySqlLexer.java @@ -64,19 +64,19 @@ public class MySqlLexer extends Lexer { super(input); super.keywods = DEFAULT_MYSQL_KEYWORDS; } - + public void scanSharp() { if (ch != '#') { throw new ParserException("illegal stat"); } - + if (charAt(pos + 1) == '{') { scanVariable(); return; } - + Token lastToken = this.token; - + scanChar(); mark = pos; bufPos = 0; @@ -102,10 +102,10 @@ public class MySqlLexer extends Lexer { scanChar(); bufPos++; } - + stringVal = subString(mark, bufPos); token = Token.LINE_COMMENT; - + if (commentHandler != null && commentHandler.handle(lastToken, stringVal)) { return; } @@ -315,7 +315,7 @@ public class MySqlLexer extends Lexer { switch (ch) { case '\0': - putChar('\0'); + putChar(ch = '\0'); break; case '\'': putChar('\''); @@ -345,20 +345,19 @@ public class MySqlLexer extends Lexer { putChar(ch); break; } - scanChar(); - } - - if (ch == '\'') { - scanChar(); - if (ch != '\'') { - token = LITERAL_CHARS; - break; - } else { - initBuff(bufPos); - arraycopy(mark + 1, buf, 0, bufPos); - hasSpecial = true; - putChar('\''); - continue; + } else { + if (ch == '\'') { + scanChar(); + if (ch != '\'') { + token = LITERAL_CHARS; + break; + } else { + initBuff(bufPos); + arraycopy(mark + 1, buf, 0, bufPos); + hasSpecial = true; + putChar('\''); + continue; + } } } @@ -438,7 +437,7 @@ public class MySqlLexer extends Lexer { if (commentHandler != null && commentHandler.handle(lastToken, stringVal)) { return; } - + if (!isAllowComment()) { throw new NotAllowCommentException(); } @@ -474,7 +473,7 @@ public class MySqlLexer extends Lexer { stringVal = subString(mark, bufPos + 1); token = Token.LINE_COMMENT; - + if (commentHandler != null && commentHandler.handle(lastToken, stringVal)) { return; } @@ -482,7 +481,7 @@ public class MySqlLexer extends Lexer { if (!isAllowComment()) { throw new NotAllowCommentException(); } - + return; } } diff --git a/src/main/java/com/alibaba/druid/sql/parser/SQLExprParser.java b/src/main/java/com/alibaba/druid/sql/parser/SQLExprParser.java index 56ac42f7df..78fb8bc140 100644 --- a/src/main/java/com/alibaba/druid/sql/parser/SQLExprParser.java +++ b/src/main/java/com/alibaba/druid/sql/parser/SQLExprParser.java @@ -1210,7 +1210,7 @@ public class SQLExprParser extends SQLParser { if (lexer.token() == Token.ESCAPE) { lexer.nextToken(); - rightExp = expr(); + rightExp = primary(); expr = new SQLBinaryOpExpr(expr, SQLBinaryOperator.Escape, rightExp); } } else if (lexer.token() == (Token.NOT)) { diff --git a/src/main/java/com/alibaba/druid/sql/visitor/SQLEvalVisitorUtils.java b/src/main/java/com/alibaba/druid/sql/visitor/SQLEvalVisitorUtils.java index a75344adfc..3ae7ff0da6 100644 --- a/src/main/java/com/alibaba/druid/sql/visitor/SQLEvalVisitorUtils.java +++ b/src/main/java/com/alibaba/druid/sql/visitor/SQLEvalVisitorUtils.java @@ -570,8 +570,12 @@ public class SQLEvalVisitorUtils { public static boolean visit(SQLEvalVisitor visitor, SQLHexExpr x) { String hex = x.getHex(); byte[] bytes = HexBin.decode(hex); - String val = new String(bytes); - x.putAttribute(EVAL_VALUE, val); + if (bytes == null) { + x.putAttribute(EVAL_VALUE, EVAL_ERROR); + } else { + String val = new String(bytes); + x.putAttribute(EVAL_VALUE, val); + } return true; } @@ -807,9 +811,13 @@ public class SQLEvalVisitorUtils { x.putAttribute(EVAL_VALUE, val); break; case NOT: - case Not: - x.putAttribute(EVAL_VALUE, !castToBoolean(val)); + case Not: { + Boolean booleanVal = castToBoolean(val); + if (booleanVal != null) { + x.putAttribute(EVAL_VALUE, !booleanVal); + } break; + } case Plus: x.putAttribute(EVAL_VALUE, val); break; @@ -1368,9 +1376,9 @@ public class SQLEvalVisitorUtils { BigDecimal decimalA = castToDecimal(a); BigDecimal decimalB = castToDecimal(b); if (decimalB.scale() < decimalA.scale()) { - decimalB.setScale(decimalA.scale()); + decimalB = decimalB.setScale(decimalA.scale()); } - return decimalA.divide(decimalB); + return decimalA.divide(decimalB, BigDecimal.ROUND_HALF_UP); } if (a instanceof Double || b instanceof Double) { diff --git a/src/main/java/com/alibaba/druid/wall/WallConfig.java b/src/main/java/com/alibaba/druid/wall/WallConfig.java index 7996d730d6..e417b7d0fd 100644 --- a/src/main/java/com/alibaba/druid/wall/WallConfig.java +++ b/src/main/java/com/alibaba/druid/wall/WallConfig.java @@ -36,7 +36,9 @@ public class WallConfig implements WallConfigMBean { private boolean createTableAllow = true; private boolean dropTableAllow = true; private boolean alterTableAllow = true; + private boolean conditionAndAlwayTrueAllow = false; + private boolean conditionDoubleConstAllow = false; private boolean selectAllColumnAllow = true; @@ -110,6 +112,14 @@ public class WallConfig implements WallConfigMBean { } + public boolean isConditionDoubleConstAllow() { + return conditionDoubleConstAllow; + } + + public void setConditionDoubleConstAllow(boolean conditionDoubleConstAllow) { + this.conditionDoubleConstAllow = conditionDoubleConstAllow; + } + public boolean isLimitZeroAllow() { return limitZeroAllow; } 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 865dff8342..46e7f4965b 100644 --- a/src/main/java/com/alibaba/druid/wall/spi/WallVisitorUtils.java +++ b/src/main/java/com/alibaba/druid/wall/spi/WallVisitorUtils.java @@ -164,7 +164,7 @@ public class WallVisitorUtils { public static void check(WallVisitor visitor, SQLSelectItem x) { SQLExpr expr = x.getExpr(); - + if (expr instanceof SQLVariantRefExpr) { if ("@".equals(((SQLVariantRefExpr) expr).getName())) { addViolation(visitor, ErrorCode.EVIL_NAME, "@ not allow", x); @@ -223,14 +223,16 @@ public class WallVisitorUtils { SQLExpr where = x.getWhere(); if (where != null) { - if (queryBlockFromIsNull(visitor, x, false)) { - addViolation(visitor, ErrorCode.EMPTY_QUERY_HAS_CONDITION, "empty select has condition", x); - } - where.setParent(x); checkCondition(visitor, x.getWhere()); - if (Boolean.TRUE == getConditionValue(visitor, where, visitor.getConfig().isSelectWhereAlwayTrueCheck())) { + Object whereValue = getConditionValue(visitor, where, visitor.getConfig().isSelectWhereAlwayTrueCheck()); + + if (queryBlockFromIsNull(visitor, x, false) && whereValue != null) { + addViolation(visitor, ErrorCode.EMPTY_QUERY_HAS_CONDITION, "empty select has condition", x); + } + + if (Boolean.TRUE == whereValue) { boolean isSimpleConstExpr = false; SQLExpr first = getFirst(where); @@ -672,22 +674,24 @@ public class WallVisitorUtils { } if (x.getOperator() == SQLBinaryOperator.BooleanAnd) { - if (rightResult != null && x.getLeft() instanceof SQLBinaryOpExpr) { - SQLBinaryOpExpr leftBinaryOpExpr = (SQLBinaryOpExpr) x.getLeft(); + if (visitor != null && !visitor.getConfig().isConditionDoubleConstAllow()) { + if (rightResult != null && x.getLeft() instanceof SQLBinaryOpExpr) { + SQLBinaryOpExpr leftBinaryOpExpr = (SQLBinaryOpExpr) x.getLeft(); - if (leftBinaryOpExpr.getOperator() != SQLBinaryOperator.BooleanAnd // - && leftBinaryOpExpr.getOperator() != SQLBinaryOperator.BooleanOr // - && leftResult != null // - && visitor != null) { - addViolation(visitor, ErrorCode.DOUBLE_CONST_CONDITION, "double const condition", x); - } - - if (leftBinaryOpExpr.getOperator() == SQLBinaryOperator.BooleanAnd // - || leftBinaryOpExpr.getOperator() == SQLBinaryOperator.BooleanOr) { - Object leftRightVal = getValue(leftBinaryOpExpr.getRight()); - if (leftRightVal != null) { + if (leftBinaryOpExpr.getOperator() != SQLBinaryOperator.BooleanAnd // + && leftBinaryOpExpr.getOperator() != SQLBinaryOperator.BooleanOr // + && leftResult != null // + && visitor != null) { addViolation(visitor, ErrorCode.DOUBLE_CONST_CONDITION, "double const condition", x); } + + if (leftBinaryOpExpr.getOperator() == SQLBinaryOperator.BooleanAnd // + || leftBinaryOpExpr.getOperator() == SQLBinaryOperator.BooleanOr) { + Object leftRightVal = getValue(leftBinaryOpExpr.getRight()); + if (leftRightVal != null) { + addViolation(visitor, ErrorCode.DOUBLE_CONST_CONDITION, "double const condition", x); + } + } } } diff --git a/src/test/java/com/alibaba/druid/bvt/filter/wall/MySqlWallTest137.java b/src/test/java/com/alibaba/druid/bvt/filter/wall/MySqlWallTest137.java new file mode 100644 index 0000000000..1735ee3390 --- /dev/null +++ b/src/test/java/com/alibaba/druid/bvt/filter/wall/MySqlWallTest137.java @@ -0,0 +1,35 @@ +/* + * 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 MySqlWallTest137 extends TestCase { + + public void test_false() throws Exception { + WallProvider provider = new MySqlWallProvider(); + + Assert.assertTrue(provider.checkValid("select bi.title from bbt_item_chd_3 bi " // + + "where bi.title = '具8\\'\\'/200mm迷OK-6295'" + + " and bi.item_id <> null and bi.nick = '营店'")); + } + +} diff --git a/src/test/java/com/alibaba/druid/bvt/filter/wall/MySqlWallTest138.java b/src/test/java/com/alibaba/druid/bvt/filter/wall/MySqlWallTest138.java new file mode 100644 index 0000000000..dd9cce22e4 --- /dev/null +++ b/src/test/java/com/alibaba/druid/bvt/filter/wall/MySqlWallTest138.java @@ -0,0 +1,43 @@ +/* + * 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 MySqlWallTest138 extends TestCase { + + public void test_false() throws Exception { + WallProvider provider = new MySqlWallProvider(); + + String sql = "INSERT INTO T01_CHECKIN_CUSTOMER" // + + "(WEB_USER_ID,NAME,COUNTRY,PROVINCE,CITY" // + + ",POSTCODE,PHONE,FAX,EMAIL,ADDRESS,FIRST_NAME,LAST_NAME,sex) " // + + "select 2,null,'4225',null,'beijing','','1','','1223@123.com','beijing','booking','test',null "// + + "from dual " // + + "where not exists ("// + + " select EMAIL" // + + " from T01_CHECKIN_CUSTOMER" // + + " where WEB_USER_ID=2 and EMAIL='1223@123.com'" // + + ")"; + Assert.assertTrue(provider.checkValid(sql)); + } + +} diff --git a/src/test/java/com/alibaba/druid/bvt/filter/wall/MySqlWallTest75.java b/src/test/java/com/alibaba/druid/bvt/filter/wall/MySqlWallTest75.java index b2cec6a48c..2e48a82279 100644 --- a/src/test/java/com/alibaba/druid/bvt/filter/wall/MySqlWallTest75.java +++ b/src/test/java/com/alibaba/druid/bvt/filter/wall/MySqlWallTest75.java @@ -33,13 +33,15 @@ public class MySqlWallTest75 extends TestCase { public void test_false() throws Exception { WallProvider provider = new MySqlWallProvider(); - + provider.getConfig().setCommentAllow(true); Assert.assertFalse(provider.checkValid(// - "UPDATE friends_a SET requests='-^B}q^A(X \\0\\0\\0176403924cdatetime\\ndatetime\\nq^BU\\n^G--\\Z^K:5^Hw.-Rq^CX \\0\\0\\0942515122h^BU\\n^G--^X^G^^$\\n^NӅRq^DX \\0\\0\\0760857294h^BU\\n^G-- ^F8+ ---Rq^EX \\0\\0\\0207000491h^BU\\n^G--^X^E^_^L^F-$-Rq^FX \\0\\0\\0281067699h^BU\\n^G--^B^O^C-^A<13>Rq^GX \\0\\0\\0941678014h^BU\\n^G--^\\^W^N^W^F-$-Rq^HX \\0\\0\\0840070155h^BU\\n^G--^\\^L\\n6^D*ʅRq X \\0\\0\\0468440035h^BU\\n^G--^V^W*^N^Bp^K-Rq\\nU 169240315h^BU\\n^G--^W^U^W1^D-m-Rq^KX \\0\\0\\0199411251h^BU\\n^G--^V^W%^^^A---Rq^LU 210660648h^BU\\n^G--^\\^W^Y-^F\\Zd-Rq\\rU 262672217h^BU\\n^G--\\Z^V2:^O^U--Rq^NX \\0\\0\\0952838443h^BU\\n^G--^\\^W!7\\r-{-Rq^OX \\0\\0\\0263642777h^BU\\n^G--^B^U/^D^G-̅Rq^PX \\0\\0\\0286685152h^BU\\n^G--^W^T3,^Ggs-Rq^QU 290976173h^BU\\n^G--^\\^V)^X^D---Rq^RX \\0\\0\\0825427842h^BU\\n^G--\\Z^V;^Q^N- -Rq^SX \\0\\0\\0399352674h^BU\\n^G--^\\^V-0^KC\\0-Rq^TX \\0\\0\\0429293778h^BU\\n^G--^Y^U ^]^C-��Rq^UX \\0\\0\\0796702973h^BU\\n^G--^Y^S^U#^F\\\\^W-Rq^Vu.',friends='-^B}q^A(X \\0\\0\\0288854421cdatetime\\ndatetime\\nq^BU\\n^G--^[^N38^L6---q^CX \\0\\0\\0307943786h^BU\\n^G--^F^V7 ^D---Rq^DX \\0\\0\\0290783072NX \\0\\0\\0498070760NX \\0\\0\\0457575155NX \\0\\0\\0304215892h^BU\\n^G--^F^W^L+^L---Rq^EX \\0\\0\\0300254457h^BU\\n^G--^F^G$)^A---Rq^FX \\0\\0\\0252042226h^BU\\n^G-- ^R8\\r ----q^GX \\0\\0\\0697110711NX \\0\\0\\0809118053h^BU\\n^G-- ^L^H^O\\0ɲ-Rq^HX \\0\\0\\0293303495h^BU\\n^G-- ^T!.^B/ʅRq X \\0\\0\\0302651538h^BU\\n^G--^G^P)^C^Fn---q\\nU 888879887h^BU\\n^G--^H^W.*^G---Rq^KX \\0\\0\\0240865621h^BU\\n^G--^G\\n2;\\n---Rq^LU 300728616h^BU\\n^G--^A^L^N8\\0\\'--Rq\\rX \\0\\0\\0856456443NX \\0\\0\\0302371154h^BU\\n^G--^A^Q^R^^\\0---Rq^NX \\0\\0\\0696458616h^BU\\n^G--^G\\n98\\n---Rq^OU 297082613NX \\0\\0\\0811281930h^BU\\n^G--\\n^Q^P^X^L^OɅRq^PU 300986758h^BU\\n^G--^F^F\\r3^G-$-Rq^QU 276325435h^BU\\n^G--^B^P^P^T^E^N8-Rq^RX \\0\\0\\0299082034h^BU\\n^G--^H^W^_^Q^D<--Rq^SX \\0\\0\\0171238051h^BU\\n^G--\\n\\r)^S^Dܢ-Rq^TX \\0\\0\\0780724792h^BU\\n^G--\\n^N+ ^F*>-Rq^UX \\0\\0\\0893552392h^BU\\n^G--\\n^N^_-^K^L--Rq^VX \\0\\0\\0590290136h^BU\\n^G-- \\r^Y0\\r --Rq^WX \\0\\0\\0302913387h^BU\\n^G--^C^K#,\\0^X9-Rq^XX \\0\\0\\0252736446NX \\0\\0\\0302360033h^BU\\n^G--^C^O^A^^^H-[-Rq^YU 276564368h^BU\\n^G--\\n\\r:+^K-q-Rq\\ZX \\0\\0\\0296693715h^BU\\n^G-- ^G^[/^A-F-Rq^[X \\0\\0\\0223225019h^BU\\n^G-- ^S^X^C\\07\\Z-Rq^\\X \\0\\0\\0232453764h^BU\\n^G--^_\\r3^V\\0---Rq^]U 297276051h^BU\\n^G--^C^K/4^K-؅Rq^^X \\0\\0\\0184978889NX \\0\\0\\0813351784h^BU\\n^G--^H^H%^X^E&^S-Rq^_X \\0\\0\\03028705")); + "UPDATE friends_a SET requests='-^B}q^A(X \\0\\0\\0176403924cdatetime\\ndatetime\\nq^BU\\n^G--\\Z^K:5^Hw.-Rq^CX \\0\\0\\0942515122h^BU\\n^G--^X^G^^$\\n^NӅRq^DX \\0\\0\\0760857294h^BU\\n^G-- ^F8+ ---Rq^EX \\0\\0\\0207000491h^BU\\n^G--^X^E^_^L^F-$-Rq^FX \\0\\0\\0281067699h^BU\\n^G--^B^O^C-^A<13>Rq^GX \\0\\0\\0941678014h^BU\\n^G--^\\^W^N^W^F-$-Rq^HX \\0\\0\\0840070155h^BU\\n^G--^\\^L\\n6^D*ʅRq X \\0\\0\\0468440035h^BU\\n^G--^V^W*^N^Bp^K-Rq\\nU 169240315h^BU\\n^G--^W^U^W1^D-m-Rq^KX \\0\\0\\0199411251h^BU\\n^G--^V^W%^^^A---Rq^LU 210660648h^BU\\n^G--^\\^W^Y-^F\\Zd-Rq\\rU 262672217h^BU\\n^G--\\Z^V2:^O^U--Rq^NX \\0\\0\\0952838443h^BU\\n^G--^\\^W!7\\r-{-Rq^OX \\0\\0\\0263642777h^BU\\n^G--^B^U/^D^G-̅Rq^PX \\0\\0\\0286685152h^BU\\n^G--^W^T3,^Ggs-Rq^QU 290976173h^BU\\n^G--^\\^V)^X^D---Rq^RX \\0\\0\\0825427842h^BU\\n^G--\\Z^V;^Q^N- -Rq^SX \\0\\0\\0399352674h^BU\\n^G--^\\^V-0^KC\\0-Rq^TX \\0\\0\\0429293778h^BU\\n^G--^Y^U ^]^C-��Rq^UX \\0\\0\\0796702973h^BU\\n^G--^Y^S^U#^F\\\\^W-Rq^Vu.'"// + + ",friends='-^B}q^A(X \\0\\0\\0288854421cdatetime\\ndatetime\\nq^BU\\n^G--^[^N38^L6---q^CX \\0\\0\\0307943786h^BU\\n^G--^F^V7 ^D---Rq^DX \\0\\0\\0290783072NX \\0\\0\\0498070760NX \\0\\0\\0457575155NX \\0\\0\\0304215892h^BU\\n^G--^F^W^L+^L---Rq^EX \\0\\0\\0300254457h^BU\\n^G--^F^G$)^A---Rq^FX \\0\\0\\0252042226h^BU\\n^G-- ^R8\\r ----q^GX \\0\\0\\0697110711NX \\0\\0\\0809118053h^BU\\n^G-- ^L^H^O\\0ɲ-Rq^HX \\0\\0\\0293303495h^BU\\n^G-- ^T!.^B/ʅRq X \\0\\0\\0302651538h^BU\\n^G--^G^P)^C^Fn---q\\nU 888879887h^BU\\n^G--^H^W.*^G---Rq^KX \\0\\0\\0240865621h^BU\\n^G--^G\\n2;\\n---Rq^LU 300728616h^BU\\n^G--^A^L^N8\\0\\'" // + + "--Rq\\rX \\0\\0\\0856456443NX \\0\\0\\0302371154h^BU\\n^G--^A^Q^R^^\\0---Rq^NX \\0\\0\\0696458616h^BU\\n^G--^G\\n98\\n---Rq^OU 297082613NX \\0\\0\\0811281930h^BU\\n^G--\\n^Q^P^X^L^OɅRq^PU 300986758h^BU\\n^G--^F^F\\r3^G-$-Rq^QU 276325435h^BU\\n^G--^B^P^P^T^E^N8-Rq^RX \\0\\0\\0299082034h^BU\\n^G--^H^W^_^Q^D<--Rq^SX \\0\\0\\0171238051h^BU\\n^G--\\n\\r)^S^Dܢ-Rq^TX \\0\\0\\0780724792h^BU\\n^G--\\n^N+ ^F*>-Rq^UX \\0\\0\\0893552392h^BU\\n^G--\\n^N^_-^K^L--Rq^VX \\0\\0\\0590290136h^BU\\n^G-- \\r^Y0\\r --Rq^WX \\0\\0\\0302913387h^BU\\n^G--^C^K#,\\0^X9-Rq^XX \\0\\0\\0252736446NX \\0\\0\\0302360033h^BU\\n^G--^C^O^A^^^H-[-Rq^YU 276564368h^BU\\n^G--\\n\\r:+^K-q-Rq\\ZX \\0\\0\\0296693715h^BU\\n^G-- ^G^[/^A-F-Rq^[X \\0\\0\\0223225019h^BU\\n^G-- ^S^X^C\\07\\Z-Rq^\\X \\0\\0\\0232453764h^BU\\n^G--^_\\r3^V\\0---Rq^]U 297276051h^BU\\n^G--^C^K/4^K-؅Rq^^X \\0\\0\\0184978889NX \\0\\0\\0813351784h^BU\\n^G--^H^H%^X^E&^S-Rq^_X \\0\\0\\03028705")); - Assert.assertEquals(1, provider.getTableStats().size()); + Assert.assertEquals(0, provider.getTableStats().size()); } } diff --git a/src/test/java/com/alibaba/druid/test/wall/MySqlResourceWallTest.java b/src/test/java/com/alibaba/druid/test/wall/MySqlResourceWallTest.java new file mode 100644 index 0000000000..881354509f --- /dev/null +++ b/src/test/java/com/alibaba/druid/test/wall/MySqlResourceWallTest.java @@ -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.test.wall; + +import java.io.File; +import java.io.FileInputStream; + +import junit.framework.TestCase; + +import com.alibaba.druid.util.Utils; +import com.alibaba.druid.wall.Violation; +import com.alibaba.druid.wall.WallCheckResult; +import com.alibaba.druid.wall.WallProvider; +import com.alibaba.druid.wall.spi.MySqlWallProvider; + +public class MySqlResourceWallTest extends TestCase { + + private String[] items; + + protected void setUp() throws Exception { +// File file = new File("/home/wenshao/error_sql"); + File file = new File("/home/wenshao/scan_result"); + FileInputStream is = new FileInputStream(file); + String text = Utils.read(is); + is.close(); + items = text.split("\\|\\n\\|"); + } + + public void test_false() throws Exception { + WallProvider provider = new MySqlWallProvider(); + + provider.getConfig().setConditionDoubleConstAllow(true); + + provider.getConfig().setUseAllow(true); + provider.getConfig().setStrictSyntaxCheck(false); + provider.getConfig().setMultiStatementAllow(true); + provider.getConfig().setConditionAndAlwayTrueAllow(true); + provider.getConfig().setNoneBaseStatementAllow(true); + provider.getConfig().setSelectUnionCheck(false); + provider.getConfig().setSchemaCheck(true); + provider.getConfig().setLimitZeroAllow(true); + provider.getConfig().setCommentAllow(true); + + for (int i = 0; i < items.length; ++i) { + String sql = items[i]; + if (sql.indexOf("''=''") != -1) { + continue; + } +// if (i <= 121) { +// continue; +// } + WallCheckResult result = provider.check(sql); + if (result.getViolations().size() > 0) { + Violation violation = result.getViolations().get(0); + System.out.println("error (" + i + ") : " + violation.getMessage()); + System.out.println(sql); + break; + } + } + System.out.println(provider.getViolationCount()); +// 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)); + } + +}