mirror of
https://github.com/alibaba/druid.git
synced 2023-03-04 19:17:16 +00:00
add sql wall suppport
This commit is contained in:
@@ -3,6 +3,7 @@ package com.alibaba.druid.filter.wall;
|
||||
import java.sql.SQLException;
|
||||
import java.util.Properties;
|
||||
|
||||
import com.alibaba.druid.DruidRuntimeException;
|
||||
import com.alibaba.druid.filter.FilterAdapter;
|
||||
import com.alibaba.druid.filter.FilterChain;
|
||||
import com.alibaba.druid.filter.wall.spi.MySqlWallProvider;
|
||||
@@ -17,13 +18,45 @@ import com.alibaba.druid.util.JdbcUtils;
|
||||
|
||||
public class WallFilter extends FilterAdapter {
|
||||
|
||||
private boolean inited = false;
|
||||
|
||||
private WallProvider provider;
|
||||
|
||||
private boolean loadDefault;
|
||||
|
||||
private boolean loadExtend;
|
||||
|
||||
@Override
|
||||
public void init(DataSourceProxy dataSource) {
|
||||
this.dataSource = dataSource;
|
||||
|
||||
provider = createWallProvider(dataSource.getDbType());
|
||||
|
||||
this.inited = true;
|
||||
}
|
||||
|
||||
public boolean isLoadDefault() {
|
||||
return loadDefault;
|
||||
}
|
||||
|
||||
public void checkInit() {
|
||||
if (inited) {
|
||||
throw new DruidRuntimeException("wall filter is inited");
|
||||
}
|
||||
}
|
||||
|
||||
public void setLoadDefault(boolean loadDefault) {
|
||||
checkInit();
|
||||
this.loadDefault = loadDefault;
|
||||
}
|
||||
|
||||
public boolean isLoadExtend() {
|
||||
return loadExtend;
|
||||
}
|
||||
|
||||
public void setLoadExtend(boolean loadExtend) {
|
||||
checkInit();
|
||||
this.loadExtend = loadExtend;
|
||||
}
|
||||
|
||||
@Override
|
||||
@@ -168,11 +201,11 @@ public class WallFilter extends FilterAdapter {
|
||||
|
||||
public WallProvider createWallProvider(String dbType) {
|
||||
if (JdbcUtils.MYSQL.equals(dbType)) {
|
||||
return new MySqlWallProvider();
|
||||
return new MySqlWallProvider(this.loadDefault, this.loadExtend);
|
||||
}
|
||||
|
||||
if (JdbcUtils.ORACLE.equals(dbType)) {
|
||||
return new OracleWallProvider();
|
||||
return new OracleWallProvider(this.loadDefault, this.loadExtend);
|
||||
}
|
||||
|
||||
throw new IllegalStateException("dbType not support : " + dbType);
|
||||
|
||||
@@ -8,19 +8,32 @@ import com.alibaba.druid.sql.parser.SQLStatementParser;
|
||||
public class MySqlWallProvider extends WallProvider {
|
||||
|
||||
public MySqlWallProvider(){
|
||||
loadDefault();
|
||||
|
||||
this(true, true);
|
||||
}
|
||||
|
||||
public MySqlWallProvider(boolean loadDefault, boolean loadExtend){
|
||||
if (loadDefault) {
|
||||
loadDefault();
|
||||
}
|
||||
|
||||
if (loadExtend) {
|
||||
loadExtend();
|
||||
}
|
||||
}
|
||||
|
||||
public void loadExtend() {
|
||||
WallVisitorUtils.loadResource(this.permitNames, "META-INF/druid-filter-wall-permit-name-mysql.txt");
|
||||
WallVisitorUtils.loadResource(this.permitSchemas, "META-INF/druid-filter-wall-permit-schema-mysql.txt");
|
||||
WallVisitorUtils.loadResource(this.permitFunctions, "META-INF/druid-filter-wall-permit-function-mysql.txt");
|
||||
WallVisitorUtils.loadResource(this.permitTables, "META-INF/druid-filter-wall-permit-table-mysql.txt");
|
||||
WallVisitorUtils.loadResource(this.permitObjects, "META-INF/druid-filter-wall-permit-object-mysql.txt");
|
||||
}
|
||||
|
||||
|
||||
public void loadDefault() {
|
||||
WallVisitorUtils.loadResource(this.permitNames, "META-INF/druid-filter-wall-permit-name-mysql-default.txt");
|
||||
WallVisitorUtils.loadResource(this.permitSchemas, "META-INF/druid-filter-wall-permit-schema-mysql-default.txt");
|
||||
WallVisitorUtils.loadResource(this.permitFunctions, "META-INF/druid-filter-wall-permit-function-mysql-default.txt");
|
||||
WallVisitorUtils.loadResource(this.permitFunctions,
|
||||
"META-INF/druid-filter-wall-permit-function-mysql-default.txt");
|
||||
WallVisitorUtils.loadResource(this.permitTables, "META-INF/druid-filter-wall-permit-table-mysql-default.txt");
|
||||
WallVisitorUtils.loadResource(this.permitObjects, "META-INF/druid-filter-wall-permit-object-mysql-default.txt");
|
||||
}
|
||||
|
||||
@@ -8,8 +8,20 @@ import com.alibaba.druid.sql.parser.SQLStatementParser;
|
||||
public class OracleWallProvider extends WallProvider {
|
||||
|
||||
public OracleWallProvider(){
|
||||
loadDefault();
|
||||
this(true, true);
|
||||
}
|
||||
|
||||
public OracleWallProvider(boolean loadDefault, boolean loadExtend){
|
||||
if (loadDefault) {
|
||||
loadDefault();
|
||||
}
|
||||
|
||||
if (loadExtend) {
|
||||
loadExtend();
|
||||
}
|
||||
}
|
||||
|
||||
public void loadExtend() {
|
||||
WallVisitorUtils.loadResource(this.permitNames, "META-INF/druid-filter-wall-permit-name-oracle.txt");
|
||||
WallVisitorUtils.loadResource(this.permitSchemas, "META-INF/druid-filter-wall-permit-schema-oracle.txt");
|
||||
WallVisitorUtils.loadResource(this.permitFunctions, "META-INF/druid-filter-wall-permit-function-oracle.txt");
|
||||
@@ -17,6 +29,15 @@ public class OracleWallProvider extends WallProvider {
|
||||
WallVisitorUtils.loadResource(this.permitObjects, "META-INF/druid-filter-wall-permit-object-oracle.txt");
|
||||
}
|
||||
|
||||
public void loadDefault() {
|
||||
WallVisitorUtils.loadResource(this.permitNames, "META-INF/druid-filter-wall-permit-name-oracle-default.txt");
|
||||
WallVisitorUtils.loadResource(this.permitSchemas, "META-INF/druid-filter-wall-permit-schema-oracle-default.txt");
|
||||
WallVisitorUtils.loadResource(this.permitFunctions,
|
||||
"META-INF/druid-filter-wall-permit-function-oracle-default.txt");
|
||||
WallVisitorUtils.loadResource(this.permitTables, "META-INF/druid-filter-wall-permit-table-oracle-default.txt");
|
||||
WallVisitorUtils.loadResource(this.permitObjects, "META-INF/druid-filter-wall-permit-object-oracle-default.txt");
|
||||
}
|
||||
|
||||
@Override
|
||||
public SQLStatementParser createParser(String sql) {
|
||||
return new OracleStatementParser(sql);
|
||||
@@ -27,12 +48,4 @@ public class OracleWallProvider extends WallProvider {
|
||||
return new OracleWallVisitor(this);
|
||||
}
|
||||
|
||||
public void loadDefault() {
|
||||
WallVisitorUtils.loadResource(this.permitNames, "META-INF/druid-filter-wall-permit-name-oracle-default.txt");
|
||||
WallVisitorUtils.loadResource(this.permitSchemas, "META-INF/druid-filter-wall-permit-schema-oracle-default.txt");
|
||||
WallVisitorUtils.loadResource(this.permitFunctions,
|
||||
"META-INF/druid-filter-wall-permit-function-oracle-default.txt");
|
||||
WallVisitorUtils.loadResource(this.permitTables, "META-INF/druid-filter-wall-permit-table-oracle-default.txt");
|
||||
WallVisitorUtils.loadResource(this.permitObjects, "META-INF/druid-filter-wall-permit-object-oracle-default.txt");
|
||||
}
|
||||
}
|
||||
|
||||
@@ -41,7 +41,7 @@ import com.alibaba.druid.util.JdbcUtils;
|
||||
public class WallVisitorUtils {
|
||||
|
||||
private final static Log LOG = LogFactory.getLog(WallVisitorUtils.class);
|
||||
|
||||
|
||||
public static void check(WallVisitor visitor, SQLPropertyExpr x) {
|
||||
if (x.getOwner() instanceof SQLIdentifierExpr) {
|
||||
String owner = x.getOwner().toString();
|
||||
@@ -56,7 +56,7 @@ public class WallVisitorUtils {
|
||||
if (x == null) {
|
||||
return;
|
||||
}
|
||||
|
||||
|
||||
if (Boolean.TRUE == getValue(x)) {
|
||||
visitor.getViolations().add(new IllegalSQLObjectViolation(SQLUtils.toSQLString(x)));
|
||||
}
|
||||
@@ -85,15 +85,32 @@ public class WallVisitorUtils {
|
||||
}
|
||||
}
|
||||
|
||||
if (x.getOperator() == SQLBinaryOperator.Like) {
|
||||
if (x.getRight() instanceof SQLCharExpr) {
|
||||
String text = ((SQLCharExpr) x.getRight()).getText();
|
||||
|
||||
if (text.length() >= 0) {
|
||||
for (char ch : text.toCharArray()) {
|
||||
if (ch != '%') {
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
if (leftResult == null || rightResult == null) {
|
||||
return null;
|
||||
}
|
||||
|
||||
if (x.getOperator() == SQLBinaryOperator.Equality) {
|
||||
if (x.getLeft() instanceof SQLNullExpr && x.getRight() instanceof SQLNullExpr) {
|
||||
return true;
|
||||
}
|
||||
|
||||
if (leftResult == null || rightResult == null) {
|
||||
return null;
|
||||
}
|
||||
|
||||
return leftResult.equals(rightResult);
|
||||
}
|
||||
|
||||
@@ -165,21 +182,8 @@ public class WallVisitorUtils {
|
||||
}
|
||||
}
|
||||
|
||||
if (x.getOperator() == SQLBinaryOperator.Like) {
|
||||
if (x.getRight() instanceof SQLCharExpr) {
|
||||
String text = ((SQLCharExpr) x.getRight()).getText();
|
||||
|
||||
if (text.length() >= 0) {
|
||||
for (char ch : text.toCharArray()) {
|
||||
if (ch != '%') {
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
}
|
||||
if (x.getOperator() == SQLBinaryOperator.Concat) {
|
||||
return leftResult.toString() + rightResult.toString();
|
||||
}
|
||||
|
||||
return null;
|
||||
@@ -252,6 +256,30 @@ public class WallVisitorUtils {
|
||||
}
|
||||
}
|
||||
|
||||
if ("chr".equalsIgnoreCase(methodName) && x.getParameters().size() == 1) {
|
||||
SQLExpr first = x.getParameters().get(0);
|
||||
Object firstResult = getValue(first);
|
||||
if (firstResult instanceof Number) {
|
||||
int intValue = ((Number) firstResult).intValue();
|
||||
char ch = (char) intValue;
|
||||
|
||||
return "" + ch;
|
||||
}
|
||||
}
|
||||
|
||||
if ("concat".equalsIgnoreCase(methodName)) {
|
||||
StringBuffer buf = new StringBuffer();
|
||||
for (SQLExpr expr : x.getParameters()) {
|
||||
Object value = getValue(expr);
|
||||
if (value == null) {
|
||||
return null;
|
||||
}
|
||||
|
||||
buf.append(value.toString());
|
||||
}
|
||||
return buf.toString();
|
||||
}
|
||||
|
||||
return null;
|
||||
}
|
||||
|
||||
@@ -302,6 +330,14 @@ public class WallVisitorUtils {
|
||||
}
|
||||
|
||||
public static void check(WallVisitor visitor, SQLMethodInvokeExpr x) {
|
||||
if (x.getOwner() instanceof SQLIdentifierExpr) {
|
||||
String owner = x.getOwner().toString();
|
||||
owner = WallVisitorUtils.form(owner);
|
||||
if (visitor.containsPermitObjects(owner)) {
|
||||
visitor.getViolations().add(new IllegalSQLObjectViolation(visitor.toSQL(x)));
|
||||
}
|
||||
}
|
||||
|
||||
String methodName = x.getMethodName();
|
||||
|
||||
if (visitor.getWallProvider().getPermitFunctions().contains(methodName.toLowerCase())) {
|
||||
@@ -363,8 +399,9 @@ public class WallVisitorUtils {
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (queryBlock.getSelectList().size() == 1 && queryBlock.getSelectList().get(0).getExpr() instanceof SQLAllColumnExpr) {
|
||||
|
||||
if (queryBlock.getSelectList().size() == 1
|
||||
&& queryBlock.getSelectList().get(0).getExpr() instanceof SQLAllColumnExpr) {
|
||||
if (from instanceof SQLSubqueryTableSource) {
|
||||
SQLSelectQuery subQuery = ((SQLSubqueryTableSource) from).getSelect().getQuery();
|
||||
if (queryBlockFromIsNull(subQuery)) {
|
||||
@@ -372,7 +409,7 @@ public class WallVisitorUtils {
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
boolean allIsConst = true;
|
||||
for (SQLSelectItem item : queryBlock.getSelectList()) {
|
||||
if (getValue(item.getExpr()) == null) {
|
||||
|
||||
Reference in New Issue
Block a user