AST语法树应用于sql检查
语法树,就是一颗表达式的二叉树,比如获取sql where条件的 左表达式 右表达式 ;,判断where 条件里面是不是就是没有带条件,或者没有什么用的条件 1=1,delete_flag=0
以下是blockAttackInnerInterceptor里校验sql的方法
package com.example.ast;import com.baomidou.mybatisplus.core.toolkit.StringUtils;
import com.baomidou.mybatisplus.extension.plugins.inner.BlockAttackInnerInterceptor;
import lombok.SneakyThrows;
import net.sf.jsqlparser.expression.BinaryExpression;
import net.sf.jsqlparser.expression.Expression;
import net.sf.jsqlparser.expression.Parenthesis;
import net.sf.jsqlparser.expression.operators.conditional.AndExpression;
import net.sf.jsqlparser.expression.operators.conditional.OrExpression;
import net.sf.jsqlparser.expression.operators.relational.EqualsTo;
import net.sf.jsqlparser.expression.operators.relational.IsNullExpression;
import net.sf.jsqlparser.expression.operators.relational.NotEqualsTo;
import net.sf.jsqlparser.parser.CCJSqlParserUtil;
import net.sf.jsqlparser.statement.Statement;
import net.sf.jsqlparser.statement.select.PlainSelect;
import net.sf.jsqlparser.statement.select.Select;
import net.sf.jsqlparser.statement.update.Update;public class AstDemo {public static void main(String[] args) throws Exception{// 解析 SQLStatement stmt = CCJSqlParserUtil.parse("update table a set a.status=1 where delete_flag=0 ");Update select = (net.sf.jsqlparser.statement.update.Update) stmt;Expression whereExpr = select.getWhere();boolean x = fullMatch(whereExpr, "delete_flag");//返回true就代表全表更新的where 条件System.out.println(x);}private static boolean fullMatch(Expression where, String logicField) {if (where == null) {return true;}if (StringUtils.isNotBlank(logicField)) {if (where instanceof BinaryExpression) {BinaryExpression binaryExpression = (BinaryExpression) where;if (StringUtils.equals(binaryExpression.getLeftExpression().toString(), logicField) || StringUtils.equals(binaryExpression.getRightExpression().toString(), logicField)) {return true;}}if (where instanceof IsNullExpression) {IsNullExpression binaryExpression = (IsNullExpression) where;if (StringUtils.equals(binaryExpression.getLeftExpression().toString(), logicField)) {return true;}}}if (where instanceof EqualsTo) {// example: 1=1EqualsTo equalsTo = (EqualsTo) where;return StringUtils.equals(equalsTo.getLeftExpression().toString(), equalsTo.getRightExpression().toString());} else if (where instanceof NotEqualsTo) {// example: 1 != 2NotEqualsTo notEqualsTo = (NotEqualsTo) where;return !StringUtils.equals(notEqualsTo.getLeftExpression().toString(), notEqualsTo.getRightExpression().toString());} else if (where instanceof OrExpression) {OrExpression orExpression = (OrExpression) where;return fullMatch(orExpression.getLeftExpression(), logicField) || fullMatch(orExpression.getRightExpression(), logicField);} else if (where instanceof AndExpression) {AndExpression andExpression = (AndExpression) where;return fullMatch(andExpression.getLeftExpression(), logicField) && fullMatch(andExpression.getRightExpression(), logicField);} else if (where instanceof Parenthesis) {// example: (1 = 1)Parenthesis parenthesis = (Parenthesis) where;return fullMatch(parenthesis.getExpression(), logicField);}return false;}
}