mirror of
https://github.com/alibaba/druid.git
synced 2023-03-04 19:17:16 +00:00
improve wall filter
This commit is contained in:
@@ -37,6 +37,9 @@ public class SQLExprTableSource extends SQLTableSourceImpl {
|
||||
}
|
||||
|
||||
public void setExpr(SQLExpr expr) {
|
||||
if (expr != null) {
|
||||
expr.setParent(this);
|
||||
}
|
||||
this.expr = expr;
|
||||
}
|
||||
|
||||
|
||||
@@ -32,7 +32,7 @@ public class SQLSelect extends SQLObjectImpl {
|
||||
}
|
||||
|
||||
public SQLSelect(SQLSelectQuery query) {
|
||||
this.query = query;
|
||||
this.setQuery(query);
|
||||
}
|
||||
|
||||
public SQLWithSubqueryClause getWithSubQuery() {
|
||||
@@ -48,6 +48,9 @@ public class SQLSelect extends SQLObjectImpl {
|
||||
}
|
||||
|
||||
public void setQuery(SQLSelectQuery query) {
|
||||
if (query != null) {
|
||||
query.setParent(this);
|
||||
}
|
||||
this.query = query;
|
||||
}
|
||||
|
||||
|
||||
@@ -33,12 +33,11 @@ public class SQLSubqueryTableSource extends SQLTableSourceImpl {
|
||||
|
||||
public SQLSubqueryTableSource(SQLSelect select, String alias){
|
||||
super(alias);
|
||||
this.select = select;
|
||||
this.setSelect(select);
|
||||
}
|
||||
|
||||
public SQLSubqueryTableSource(SQLSelect select){
|
||||
|
||||
this.select = select;
|
||||
this.setSelect(select);
|
||||
}
|
||||
|
||||
public SQLSelect getSelect() {
|
||||
@@ -46,6 +45,9 @@ public class SQLSubqueryTableSource extends SQLTableSourceImpl {
|
||||
}
|
||||
|
||||
public void setSelect(SQLSelect select) {
|
||||
if (select != null) {
|
||||
select.setParent(this);
|
||||
}
|
||||
this.select = select;
|
||||
}
|
||||
|
||||
|
||||
@@ -44,6 +44,9 @@ public class SQLUnionQuery extends SQLSelectQuery {
|
||||
}
|
||||
|
||||
public void setLeft(SQLSelectQuery left) {
|
||||
if (left != null) {
|
||||
left.setParent(this);
|
||||
}
|
||||
this.left = left;
|
||||
}
|
||||
|
||||
@@ -52,6 +55,9 @@ public class SQLUnionQuery extends SQLSelectQuery {
|
||||
}
|
||||
|
||||
public void setRight(SQLSelectQuery right) {
|
||||
if (right != null) {
|
||||
right.setParent(this);
|
||||
}
|
||||
this.right = right;
|
||||
}
|
||||
|
||||
@@ -60,6 +66,9 @@ public class SQLUnionQuery extends SQLSelectQuery {
|
||||
}
|
||||
|
||||
public void setOrderBy(SQLOrderBy orderBy) {
|
||||
if (orderBy != null) {
|
||||
orderBy.setParent(this);
|
||||
}
|
||||
this.orderBy = orderBy;
|
||||
}
|
||||
|
||||
|
||||
+3
@@ -89,6 +89,9 @@ public class MySqlDeleteStatement extends SQLDeleteStatement {
|
||||
}
|
||||
|
||||
public void setLimit(Limit limit) {
|
||||
if (limit != null) {
|
||||
limit.setParent(this);
|
||||
}
|
||||
this.limit = limit;
|
||||
}
|
||||
|
||||
|
||||
+3
@@ -165,6 +165,9 @@ public class MySqlSelectQueryBlock extends SQLSelectQueryBlock implements MySqlO
|
||||
}
|
||||
|
||||
public void setLimit(Limit limit) {
|
||||
if (limit != null) {
|
||||
limit.setParent(this);
|
||||
}
|
||||
this.limit = limit;
|
||||
}
|
||||
|
||||
|
||||
+3
@@ -57,6 +57,9 @@ public class MySqlShowBinLogEventsStatement extends MySqlStatementImpl implement
|
||||
}
|
||||
|
||||
public void setLimit(Limit limit) {
|
||||
if (limit != null) {
|
||||
limit.setParent(this);
|
||||
}
|
||||
this.limit = limit;
|
||||
}
|
||||
|
||||
|
||||
@@ -32,6 +32,9 @@ public class MySqlUnionQuery extends SQLUnionQuery implements MySqlObject {
|
||||
}
|
||||
|
||||
public void setLimit(Limit limit) {
|
||||
if (limit != null) {
|
||||
limit.setParent(this);
|
||||
}
|
||||
this.limit = limit;
|
||||
}
|
||||
|
||||
|
||||
+3
@@ -35,6 +35,9 @@ public class MySqlUpdateStatement extends SQLUpdateStatement implements MySqlSta
|
||||
}
|
||||
|
||||
public void setLimit(Limit limit) {
|
||||
if (limit != null) {
|
||||
limit.setParent(this);
|
||||
}
|
||||
this.limit = limit;
|
||||
}
|
||||
|
||||
|
||||
@@ -299,7 +299,7 @@ public class MySqlExprParser extends SQLExprParser {
|
||||
}
|
||||
|
||||
String unitVal = lexer.stringVal();
|
||||
MySqlIntervalUnit unit = MySqlIntervalUnit.valueOf(unitVal);
|
||||
MySqlIntervalUnit unit = MySqlIntervalUnit.valueOf(unitVal.toUpperCase());
|
||||
lexer.nextToken();
|
||||
|
||||
accept(Token.FROM);
|
||||
|
||||
@@ -640,6 +640,10 @@ public class MySqlStatementParser extends SQLStatementParser {
|
||||
|
||||
public SQLStatement parseShow() {
|
||||
acceptIdentifier("SHOW");
|
||||
|
||||
if (lexer.token() == Token.COMMENT) {
|
||||
lexer.nextToken();
|
||||
}
|
||||
|
||||
boolean full = false;
|
||||
if (lexer.token() == Token.FULL) {
|
||||
@@ -1508,6 +1512,10 @@ public class MySqlStatementParser extends SQLStatementParser {
|
||||
MySqlReplaceStatement stmt = new MySqlReplaceStatement();
|
||||
|
||||
acceptIdentifier(REPLACE);
|
||||
|
||||
if (lexer.token() == Token.COMMENT) {
|
||||
lexer.nextToken();
|
||||
}
|
||||
|
||||
if (identifierEquals(LOW_PRIORITY)) {
|
||||
stmt.setLowPriority(true);
|
||||
|
||||
@@ -44,6 +44,10 @@ public class IOUtils {
|
||||
InputStream in = null;
|
||||
try {
|
||||
in = Thread.currentThread().getContextClassLoader().getResourceAsStream(resource);
|
||||
if (in == null) {
|
||||
in = IOUtils.class.getResourceAsStream(resource);
|
||||
}
|
||||
|
||||
if (in == null) {
|
||||
return null;
|
||||
}
|
||||
|
||||
@@ -36,6 +36,7 @@ public class WallConfig implements WallConfigMBean {
|
||||
private boolean createTableAllow = true;
|
||||
private boolean dropTableAllow = true;
|
||||
private boolean alterTableAllow = true;
|
||||
private boolean conditionAndAlwayTrueAllow = false;
|
||||
|
||||
private boolean selectAllColumnAllow = true;
|
||||
|
||||
@@ -54,6 +55,7 @@ public class WallConfig implements WallConfigMBean {
|
||||
private boolean replaceAllow = true;
|
||||
private boolean setAllow = true;
|
||||
private boolean commitAllow = true;
|
||||
private boolean rollbackAllow = true;
|
||||
private boolean useAllow = false;
|
||||
|
||||
private boolean multiStatementAllow = false;
|
||||
@@ -107,6 +109,14 @@ public class WallConfig implements WallConfigMBean {
|
||||
|
||||
}
|
||||
|
||||
public boolean isConditionAndAlwayTrueAllow() {
|
||||
return conditionAndAlwayTrueAllow;
|
||||
}
|
||||
|
||||
public void setConditionAndAlwayTrueAllow(boolean conditionAndAlwayTrueAllow) {
|
||||
this.conditionAndAlwayTrueAllow = conditionAndAlwayTrueAllow;
|
||||
}
|
||||
|
||||
public boolean isUseAllow() {
|
||||
return useAllow;
|
||||
}
|
||||
@@ -115,7 +125,6 @@ public class WallConfig implements WallConfigMBean {
|
||||
this.useAllow = useAllow;
|
||||
}
|
||||
|
||||
|
||||
public boolean isCommitAllow() {
|
||||
return commitAllow;
|
||||
}
|
||||
@@ -124,6 +133,14 @@ public class WallConfig implements WallConfigMBean {
|
||||
this.commitAllow = commitAllow;
|
||||
}
|
||||
|
||||
public boolean isRollbackAllow() {
|
||||
return rollbackAllow;
|
||||
}
|
||||
|
||||
public void setRollbackAllow(boolean rollbackAllow) {
|
||||
this.rollbackAllow = rollbackAllow;
|
||||
}
|
||||
|
||||
public boolean isIntersectAllow() {
|
||||
return intersectAllow;
|
||||
}
|
||||
|
||||
@@ -235,7 +235,7 @@ public class MySqlWallVisitor extends MySqlASTVisitorAdapter implements WallVisi
|
||||
return false;
|
||||
}
|
||||
|
||||
if (!checkVar(x.getParent(), x.getName())) {
|
||||
if (varName.startsWith("@@") && !checkVar(x.getParent(), x.getName())) {
|
||||
violations.add(new IllegalSQLObjectViolation("variable not allow : " + x.getName(), toSQL(x)));
|
||||
}
|
||||
|
||||
|
||||
@@ -54,6 +54,7 @@ import com.alibaba.druid.sql.ast.statement.SQLExprTableSource;
|
||||
import com.alibaba.druid.sql.ast.statement.SQLInsertInto;
|
||||
import com.alibaba.druid.sql.ast.statement.SQLInsertStatement;
|
||||
import com.alibaba.druid.sql.ast.statement.SQLJoinTableSource;
|
||||
import com.alibaba.druid.sql.ast.statement.SQLRollbackStatement;
|
||||
import com.alibaba.druid.sql.ast.statement.SQLSelect;
|
||||
import com.alibaba.druid.sql.ast.statement.SQLSelectItem;
|
||||
import com.alibaba.druid.sql.ast.statement.SQLSelectQuery;
|
||||
@@ -189,7 +190,7 @@ public class WallVisitorUtils {
|
||||
SQLExpr where = x.getWhere();
|
||||
|
||||
if (where != null) {
|
||||
x.getWhere().setParent(x);
|
||||
where.setParent(x);
|
||||
checkCondition(visitor, x.getWhere());
|
||||
|
||||
if (Boolean.TRUE == getConditionValue(visitor, where, visitor.getConfig().isSelectWhereAlwayTrueCheck())) {
|
||||
@@ -205,7 +206,7 @@ public class WallVisitorUtils {
|
||||
}
|
||||
}
|
||||
|
||||
if (!isSimpleConstExpr) {
|
||||
if ((!isFirst(where)) && !isSimpleConstExpr) {
|
||||
addViolation(visitor, "select alway true condition not allow", x);
|
||||
}
|
||||
}
|
||||
@@ -522,8 +523,10 @@ public class WallVisitorUtils {
|
||||
return null;
|
||||
}
|
||||
|
||||
Object leftResult = getValue(x.getLeft());
|
||||
Object rightResult = getValue(x.getRight());
|
||||
SQLExpr left = x.getLeft();
|
||||
SQLExpr right = x.getRight();
|
||||
Object leftResult = getValue(left);
|
||||
Object rightResult = getValue(right);
|
||||
|
||||
if (x.getOperator() == SQLBinaryOperator.BooleanAnd) {
|
||||
if (Boolean.FALSE == leftResult || Boolean.FALSE == rightResult) {
|
||||
@@ -539,7 +542,14 @@ public class WallVisitorUtils {
|
||||
}
|
||||
} else if (rightResult == Boolean.TRUE) {
|
||||
final WallConditionContext current = wallConditionContextLocal.get();
|
||||
if (current != null) {
|
||||
|
||||
boolean isLikeAlwayTrue = false;
|
||||
if (right instanceof SQLBinaryOpExpr
|
||||
&& ((SQLBinaryOpExpr) right).getOperator() == SQLBinaryOperator.Like) {
|
||||
isLikeAlwayTrue = true;
|
||||
}
|
||||
|
||||
if (current != null && !isLikeAlwayTrue) {
|
||||
current.setPartAlwayTrue(true);
|
||||
}
|
||||
}
|
||||
@@ -631,7 +641,7 @@ public class WallVisitorUtils {
|
||||
final Object value = getValue(x);
|
||||
|
||||
final WallConditionContext current = wallConditionContextLocal.get();
|
||||
if (current.hasPartAlwayTrue() && alwayTrueCheck) {
|
||||
if (current.hasPartAlwayTrue() && alwayTrueCheck && !visitor.getConfig().isConditionAndAlwayTrueAllow()) {
|
||||
addViolation(visitor, "part alway true condition not allow", x);
|
||||
}
|
||||
|
||||
@@ -801,7 +811,7 @@ public class WallVisitorUtils {
|
||||
}
|
||||
|
||||
String methodName = x.getMethodName();
|
||||
|
||||
|
||||
WallContext context = WallContext.current();
|
||||
if (context != null) {
|
||||
context.incrementFunctionInvoke(methodName);
|
||||
@@ -974,29 +984,34 @@ public class WallVisitorUtils {
|
||||
|
||||
public static void loadResource(Set<String> names, String resource) {
|
||||
try {
|
||||
boolean hasResource = false;
|
||||
Enumeration<URL> e = Thread.currentThread().getContextClassLoader().getResources(resource);
|
||||
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);
|
||||
}
|
||||
}
|
||||
readFromInputStream(names, in);
|
||||
|
||||
url.openStream();
|
||||
hasResource = true;
|
||||
} finally {
|
||||
JdbcUtils.close(in);
|
||||
}
|
||||
}
|
||||
|
||||
// for aliyun odps
|
||||
if (!hasResource) {
|
||||
if (!resource.startsWith("/")) {
|
||||
resource = "/" + resource;
|
||||
}
|
||||
|
||||
InputStream in = null;
|
||||
try {
|
||||
in = WallVisitorUtils.class.getResourceAsStream(resource);
|
||||
if (in != null) {
|
||||
readFromInputStream(names, in);
|
||||
}
|
||||
} finally {
|
||||
JdbcUtils.close(reader);
|
||||
JdbcUtils.close(in);
|
||||
}
|
||||
}
|
||||
@@ -1005,6 +1020,26 @@ public class WallVisitorUtils {
|
||||
}
|
||||
}
|
||||
|
||||
private static void readFromInputStream(Set<String> names, InputStream in) throws IOException {
|
||||
BufferedReader reader = null;
|
||||
try {
|
||||
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);
|
||||
}
|
||||
}
|
||||
} finally {
|
||||
JdbcUtils.close(reader);
|
||||
}
|
||||
}
|
||||
|
||||
public static void preVisitCheck(WallVisitor visitor, SQLObject x) {
|
||||
WallConfig config = visitor.getProvider().getConfig();
|
||||
|
||||
@@ -1064,6 +1099,9 @@ public class WallVisitorUtils {
|
||||
} else if (x instanceof MySqlCommitStatement) {
|
||||
allow = config.isCommitAllow();
|
||||
denyMessage = "show not allow";
|
||||
} else if (x instanceof SQLRollbackStatement) {
|
||||
allow = config.isRollbackAllow();
|
||||
denyMessage = "show not allow";
|
||||
} else if (x instanceof SQLUseStatement) {
|
||||
allow = config.isUseAllow();
|
||||
denyMessage = "show not allow";
|
||||
|
||||
Reference in New Issue
Block a user