updateWhereAlayTrueCheck、deleteWhereAlwayTrueCheck 等永真条件检查不生效,使用mysql数据库
通过代码分析发现,检查中存在三个条件检查
if (config.isDeleteWhereAlwayTrueCheck() && visitor.isSqlEndOfComment() && !isSimpleConstExpr(where)){}
第一个和第二个条件不成立
如SQL 1:
update table_name set names=? where 2=2
delete from table_name where 2=2
该语句第二个条件不成立,SqlEndOfComment 的值判断 在 Lexer.nextToken() 通过 scanSharp() 和 scanComment(); 进行判断,但是这两个需要在 sql 包含 ‘#’ 和 ‘-’ 、‘/’ 字符时才进入
但是实际上我的 sql 中不存储这几个字符 ,所以根本不可能执行这两个方法,SqlEndOfComment 条件就根本就不会成立,所以判断该条件的意义是什么??
通过在sql后条件 -- 可以使SqlEndOfComment 成立,但是 isSimpleConstExpr 不会成立,该方法中始终返回值 为 true
如 SQL 2:
update table_name set names=? where 2=2 --
delete from table_name where 2=2 --
如 SQL 3:
update table_name set names=? where 2=2 and 1=1 and 3=3 --
delete from table_name where 2=2 and 1=1 and 3=3 --
这两个SQL 在 isSimpleConstExpr 方法中的两个位置分别成立,最终返回 true
private static boolean isSimpleConstExpr(SQLExpr sqlExpr) {
List<SQLExpr> parts = getParts(sqlExpr);
if (parts.isEmpty()) {
return false;
}
for (SQLExpr part : parts) {
if(isFirst(part)) {
Object evalValue = part.getAttribute(EVAL_VALUE);
// .....
/**
* 这里SQL 2: 会获取到 EVAL_VALUE 的值为 true , 则返回 true
*/
Boolean result = SQLEvalVisitorUtils.castToBoolean(evalValue);
if (result != null && result) {
return true;
}
}
boolean isSimpleConstExpr = false;
/**
* 这里SQL 3 会成立 isSimpleConstExpr 值为 true , 最终返回值为 true
*/
if (part == sqlExpr || part instanceof SQLLiteralExpr) {
isSimpleConstExpr = true;
} else if (part instanceof SQLBinaryOpExpr) {
// ------
}
if (!isSimpleConstExpr) {
return false;
}
}
return true;
}
所以 isSimpleConstExpr 方法的存在的意义是什么?按照我的理解,如上三种SQL应该是需要被拦截的,但是经过实际测试发现并没有被拦截,原因是 isSqlEndOfComment()、!isSimpleConstExpr(where) 两个条件不成立
2条答案
按热度按时间mv1qrgav1#
这么多年了,还是没有解决这个问题。我想禁止全表删除或更新,也不生效。
当 where后面直接跟1=1时,不会报错,但当出现【where 条件 and 1=1】时会出现报错
检查WHERE子句是否是一个永真条件,这跟我想象的不一样啊!!!
gz5pxeao2#
还会改这个bug吗? 三年了。我也遇到了