完善 SqlInjectionUtils.check 注入校验方法覆盖 UpdateWrapper 条件 checkSqlInjection() 注入检测方法
This commit is contained in:
parent
4a273f1ba2
commit
1c5ef2cfb6
@ -31,11 +31,11 @@ Mybatis 增强工具包 - 只做增强不做改变,简化`CRUD`操作
|
|||||||
# 特别用户
|
# 特别用户
|
||||||
|
|
||||||
<p>
|
<p>
|
||||||
<a href="https://flowlong.gitee.io/docs/preface.html?from=mp" target="_blank">
|
<a href="https://doc.flowlong.com?from=mp" target="_blank">
|
||||||
<img alt="AiZuDa-Logo" src="https://baomidou.com/img/azd01.png" width="160px" height="50px">
|
<img alt="AiZuDa-Logo" src="https://foruda.gitee.com/images/1715955628416785121/954c16ef_12260.png" width="160px" height="50px">
|
||||||
</a>
|
</a>
|
||||||
<a href="https://gitee.com/gz-yami/mall4j?from=mp" target="_blank">
|
<a href="https://gitee.com/gz-yami/mall4j?from=mp" target="_blank">
|
||||||
<img alt="Mybatis-Plus-Logo" src="https://baomidou.com/img/mall4j.gif" width="160px" height="50px">
|
<img alt="Mybatis-Plus-Logo" src="https://foruda.gitee.com/images/1716599753022423252/fb0139cf_12260.png" width="160px" height="50px">
|
||||||
</a>
|
</a>
|
||||||
<a href="http://github.crmeb.net/u/MyBatis-Plus" target="_blank">
|
<a href="http://github.crmeb.net/u/MyBatis-Plus" target="_blank">
|
||||||
<img alt="Crmeb-Logo" src="https://foruda.gitee.com/images/1685339553088166856/b0a6b1a4_12260.gif" width="160px" height="50px">
|
<img alt="Crmeb-Logo" src="https://foruda.gitee.com/images/1685339553088166856/b0a6b1a4_12260.gif" width="160px" height="50px">
|
||||||
|
@ -31,11 +31,11 @@
|
|||||||
# Special user
|
# Special user
|
||||||
|
|
||||||
<p>
|
<p>
|
||||||
<a href="https://flowlong.gitee.io/docs/preface.html?from=mp" target="_blank">
|
<a href="https://doc.flowlong.com?from=mp" target="_blank">
|
||||||
<img alt="AiZuDa-Logo" src="https://baomidou.com/img/azd01.png" width="160px" height="50px">
|
<img alt="AiZuDa-Logo" src="https://foruda.gitee.com/images/1715955628416785121/954c16ef_12260.png" width="160px" height="50px">
|
||||||
</a>
|
</a>
|
||||||
<a href="https://gitee.com/gz-yami/mall4j?from=mp" target="_blank">
|
<a href="https://gitee.com/gz-yami/mall4j?from=mp" target="_blank">
|
||||||
<img alt="Mybatis-Plus-Logo" src="https://baomidou.com/img/mall4j.gif" width="160px" height="50px">
|
<img alt="Mybatis-Plus-Logo" src="https://foruda.gitee.com/images/1716599753022423252/fb0139cf_12260.png" width="160px" height="50px">
|
||||||
</a>
|
</a>
|
||||||
</p>
|
</p>
|
||||||
|
|
||||||
|
@ -18,9 +18,11 @@ package com.baomidou.mybatisplus.core.conditions.update;
|
|||||||
import com.baomidou.mybatisplus.core.conditions.AbstractWrapper;
|
import com.baomidou.mybatisplus.core.conditions.AbstractWrapper;
|
||||||
import com.baomidou.mybatisplus.core.conditions.SharedString;
|
import com.baomidou.mybatisplus.core.conditions.SharedString;
|
||||||
import com.baomidou.mybatisplus.core.conditions.segments.MergeSegments;
|
import com.baomidou.mybatisplus.core.conditions.segments.MergeSegments;
|
||||||
|
import com.baomidou.mybatisplus.core.exceptions.MybatisPlusException;
|
||||||
import com.baomidou.mybatisplus.core.toolkit.CollectionUtils;
|
import com.baomidou.mybatisplus.core.toolkit.CollectionUtils;
|
||||||
import com.baomidou.mybatisplus.core.toolkit.Constants;
|
import com.baomidou.mybatisplus.core.toolkit.Constants;
|
||||||
import com.baomidou.mybatisplus.core.toolkit.StringUtils;
|
import com.baomidou.mybatisplus.core.toolkit.StringUtils;
|
||||||
|
import com.baomidou.mybatisplus.core.toolkit.sql.SqlInjectionUtils;
|
||||||
|
|
||||||
import java.util.ArrayList;
|
import java.util.ArrayList;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
@ -66,6 +68,28 @@ public class UpdateWrapper<T> extends AbstractWrapper<T, String, UpdateWrapper<T
|
|||||||
this.sqlFirst = sqlFirst;
|
this.sqlFirst = sqlFirst;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 检查 SQL 注入过滤
|
||||||
|
*/
|
||||||
|
private boolean checkSqlInjection;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 开启检查 SQL 注入
|
||||||
|
*/
|
||||||
|
public UpdateWrapper<T> checkSqlInjection() {
|
||||||
|
this.checkSqlInjection = true;
|
||||||
|
return this;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
protected String columnToString(String column) {
|
||||||
|
if (checkSqlInjection && SqlInjectionUtils.check(column)) {
|
||||||
|
throw new MybatisPlusException("Discovering SQL injection column: " + column);
|
||||||
|
}
|
||||||
|
return column;
|
||||||
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public String getSqlSet() {
|
public String getSqlSet() {
|
||||||
if (CollectionUtils.isEmpty(sqlSet)) {
|
if (CollectionUtils.isEmpty(sqlSet)) {
|
||||||
|
@ -29,7 +29,7 @@ public class SqlInjectionUtils {
|
|||||||
* SQL语法检查正则:符合两个关键字(有先后顺序)才算匹配
|
* SQL语法检查正则:符合两个关键字(有先后顺序)才算匹配
|
||||||
*/
|
*/
|
||||||
private static final Pattern SQL_SYNTAX_PATTERN = Pattern.compile("(insert|delete|update|select|create|drop|truncate|grant|alter|deny|revoke|call|execute|exec|declare|show|rename|set)" +
|
private static final Pattern SQL_SYNTAX_PATTERN = Pattern.compile("(insert|delete|update|select|create|drop|truncate|grant|alter|deny|revoke|call|execute|exec|declare|show|rename|set)" +
|
||||||
"\\s+.*(into|from|set|where|table|database|view|index|on|cursor|procedure|trigger|for|password|union|and|or)|(select\\s*\\*\\s*from\\s+)|(and|or)\\s+.*(like|=|>|<|in|between|is|not|exists)", Pattern.CASE_INSENSITIVE);
|
"\\s+.*(into|from|set|where|table|database|view|index|on|cursor|procedure|trigger|for|password|union|and|or)|(select\\s*\\*\\s*from\\s+)|(and|or)\\s+.*", Pattern.CASE_INSENSITIVE);
|
||||||
/**
|
/**
|
||||||
* 使用'、;或注释截断SQL检查正则
|
* 使用'、;或注释截断SQL检查正则
|
||||||
*/
|
*/
|
||||||
|
@ -1,7 +1,9 @@
|
|||||||
package com.baomidou.mybatisplus.core.conditions;
|
package com.baomidou.mybatisplus.core.conditions;
|
||||||
|
|
||||||
import com.baomidou.mybatisplus.core.conditions.update.UpdateWrapper;
|
import com.baomidou.mybatisplus.core.conditions.update.UpdateWrapper;
|
||||||
|
import com.baomidou.mybatisplus.core.exceptions.MybatisPlusException;
|
||||||
import com.baomidou.mybatisplus.test.User;
|
import com.baomidou.mybatisplus.test.User;
|
||||||
|
import org.junit.jupiter.api.Assertions;
|
||||||
import org.junit.jupiter.api.Test;
|
import org.junit.jupiter.api.Test;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -12,7 +14,7 @@ class UpdateWrapperTest extends BaseWrapperTest {
|
|||||||
|
|
||||||
@Test
|
@Test
|
||||||
void test1() {
|
void test1() {
|
||||||
UpdateWrapper<User> wrapper = new UpdateWrapper<User>()
|
UpdateWrapper<User> wrapper = new UpdateWrapper<User>().checkSqlInjection().eq("hi=1 or a", 123)
|
||||||
.set("name", "a", "typeHandler=org.apache.ibatis.type.StringTypeHandler")
|
.set("name", "a", "typeHandler=org.apache.ibatis.type.StringTypeHandler")
|
||||||
.set("name", "a", "typeHandler=org.apache.ibatis.type.StringTypeHandler,jdbcType=VARCHAR")
|
.set("name", "a", "typeHandler=org.apache.ibatis.type.StringTypeHandler,jdbcType=VARCHAR")
|
||||||
.set("name", "a", "typeHandler=org.apache.ibatis.type.StringTypeHandler,jdbcType=VARCHAR,numericScale=2");
|
.set("name", "a", "typeHandler=org.apache.ibatis.type.StringTypeHandler,jdbcType=VARCHAR,numericScale=2");
|
||||||
@ -21,5 +23,6 @@ class UpdateWrapperTest extends BaseWrapperTest {
|
|||||||
"name=#{ew.paramNameValuePairs.MPGENVAL2,typeHandler=org.apache.ibatis.type.StringTypeHandler,jdbcType=VARCHAR}," +
|
"name=#{ew.paramNameValuePairs.MPGENVAL2,typeHandler=org.apache.ibatis.type.StringTypeHandler,jdbcType=VARCHAR}," +
|
||||||
"name=#{ew.paramNameValuePairs.MPGENVAL3,typeHandler=org.apache.ibatis.type.StringTypeHandler,jdbcType=VARCHAR,numericScale=2}");
|
"name=#{ew.paramNameValuePairs.MPGENVAL3,typeHandler=org.apache.ibatis.type.StringTypeHandler,jdbcType=VARCHAR,numericScale=2}");
|
||||||
logParams(wrapper);
|
logParams(wrapper);
|
||||||
|
Assertions.assertThrows(MybatisPlusException.class, wrapper::getSqlSegment);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -55,6 +55,11 @@ import org.junit.jupiter.api.Test;
|
|||||||
assertSql(false,"ORDER BY field(status,'SUCCESS','FAILED','CLOSED')");
|
assertSql(false,"ORDER BY field(status,'SUCCESS','FAILED','CLOSED')");
|
||||||
assertSql(true,"ORDER BY id,'SUCCESS',''-- FAILED','CLOSED'");
|
assertSql(true,"ORDER BY id,'SUCCESS',''-- FAILED','CLOSED'");
|
||||||
assertSql(true, "or 1 = 1");
|
assertSql(true, "or 1 = 1");
|
||||||
|
assertSql(true, "and 1 = 1");
|
||||||
|
assertSql(true, "hi = 1 or abc");
|
||||||
|
assertSql(true, "(hi = 1) and abc");
|
||||||
|
assertSql(false, "orAnd");
|
||||||
|
assertSql(false, "andOr");
|
||||||
}
|
}
|
||||||
|
|
||||||
private void assertSql(boolean injection, String sql) {
|
private void assertSql(boolean injection, String sql) {
|
||||||
|
Loading…
x
Reference in New Issue
Block a user