Druid是阿里巴巴开源的一个数据源,主要用于java数据库连接池,相比spring推荐的DBCP和hibernate推荐的C3P0、Proxool数据库连接池,Druid在市场上占有绝对的优势。接下来本教程就说一下druid wallfilter配置
由上图可知,druid在处理禁用表时,并没有直观的过滤sql来达到我们的效果,而是在触发它特有的规则才会过滤。如果想达到我们所需要的效果,可以修改其源码重新打包即可。
下面是调用代码:
package com.zhibei;
import com.alibaba.druid.sql.SQLUtils;
import com.alibaba.druid.wall.Violation;
import com.alibaba.druid.wall.WallCheckResult;
import com.alibaba.druid.wall.spi.*;
import com.alibaba.druid.wall.violation.IllegalSQLObjectViolation;
import java.sql.SQLException;
import java.util.ArrayList;
import java.util.List;
import java.util.regex.Matcher;
import java.util.regex.Pattern;
public class TestDirud {
enum SQL_STATUS{
ERRSQL,
WALLSQL,
REGEXSQL,
SQL
}
enum OPERAT_STATUS{
BLOCK, //阻断
INTERCEPET, //拦截
BY //通过
}
public static void main(String[] args) throws SQLException {
String type = "mysql";
String path = "E:/Document/Hotswap/hotswap/src/main/resource/META-INF/druid/wall/";
String sql = "";
sql ="select * from person where id<3 and 1!=1";
printWallCheckResult(Judgmentvisit(type,sql,path));
sql ="select * from person where id<3 and 1=1";
printWallCheckResult(Judgmentvisit(type,sql,path));
sql = "select * from table_name where column_name LIKE '%%'";
printWallCheckResult(Judgmentvisit(type,sql,path));
sql = "select * from dual where 1=1";
System.out.println(Judgmentintercept(type,sql,path));
sql = "select * from zhibei.dual";
System.out.println(Judgmentintercept(type,sql,path));
sql = "select extractvalue(xmltype(']>'|| '&' ||'xxe;'),'/l') from zhibeixix;";
System.out.println(Judgmentintercept(type,sql,path));
}
public static void printWallCheckResult(WallCheckResult wallCheckResult ){
if (wallCheckResult!=null &&wallCheckResult.getViolations().size()>=1)
System.out.println(wallCheckResult.getSql()+" ------> "+wallCheckResult.getViolations().get(0).getMessage()+" : "+wallCheckResult.getViolations().get(0).getErrorCode());
}
public static void printWallCheckResult(Violation violation ){
if (violation!=null){
System.out.println(violation.toString() +" "+violation.getMessage()+" "+violation.getErrorCode());
}
}
//检验是否存在sql注入
public static boolean isVaildWall(String type,String sql,String path){
WallCheckResult result = getResult(type ,sql ,path);
return !result.getViolations().isEmpty();
}
//检验是否为合法sql
public static boolean isVaildSql(String type,String sql){
try {
SQLUtils.parseStatements(sql, type);
}catch (Exception e){
return false;
}
return true;
}
//检验sql入口
public static TestDirud.SQL_STATUS isVaild(String type ,String sql ,String path){
if (isVaildSql(type,sql)){
if (isVaildWall(type,sql,path)) return SQL_STATUS.WALLSQL;
else if (!isregexWall(sql,path)) return SQL_STATUS.REGEXSQL;
else return SQL_STATUS.SQL;
}else return SQL_STATUS.ERRSQL;
}
//检验是否有敏感字段
public static boolean isregexWall(String sql , String path){
if (path.endsWith("/")) {
path = path.substring(0, path.length() - 1);
}
String regex1 ="'(.*?)'";
Pattern pattern1 = Pattern.compile(regex1);
Matcher matcher = pattern1.matcher(sql);
List string = ReaderFileLine.getFileContent(path+"/deny_context.txt");
while (matcher.find()) {
for (int k=0;k violations = new ArrayList();
Violation violation = new IllegalSQLObjectViolation(1000, "Contains sensitive fields in SQL statements", sql);
violations.add(violation);
result = new WallCheckResult(null,violations,null,null,null,true);
}
return result;
}
//判断 永真、永假、LIKE永真
public static Violation Judgmentvisit(String type ,String sql ,String path){
WallCheckResult result = returnResult(type ,sql ,path);
if (!result.getViolations().isEmpty()){
return new IllegalSQLObjectViolation(0,result.getViolations().get(0).getMessage() , sql);
}else {
return new IllegalSQLObjectViolation(1,"success" , sql);
}
}
//mycat拦截
public static OPERAT_STATUS Judgmentintercept(String type ,String sql ,String path){
WallCheckResult block = returnResult(type ,sql ,path+"block/");
WallCheckResult intercept = returnResult(type ,sql ,path+"intercept/");
if (block!=null&&!block.getViolations().isEmpty()){
printWallCheckResult(block);
return OPERAT_STATUS.BLOCK;
}
else if (intercept!=null&&!intercept.getViolations().isEmpty()){
printWallCheckResult(intercept);
return OPERAT_STATUS.INTERCEPET;
}
return OPERAT_STATUS.BY;
}
}