Skip to content

Commit

Permalink
fix(data): 完善 SQL 注入验证工具类
Browse files Browse the repository at this point in the history
  • Loading branch information
Charles7c committed Aug 14, 2024
1 parent b0a2a8c commit 22ebdfe
Showing 1 changed file with 80 additions and 5 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -16,17 +16,24 @@

package top.continew.starter.data.core.util;

import java.util.Objects;
import cn.hutool.core.text.CharSequenceUtil;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import java.util.regex.Pattern;

/**
* SQL 注入验证工具类
*
* @author hubin
* @author hubin(<a href="https://github.com/baomidou/mybatis-plus">MyBatis Plus</a>)
* @author zhoujf(<a href="https://github.com/jeecgboot/JeecgBoot">JeecgBoot</a>)
* @author Charles7c
* @since 2.5.2
*/
public class SqlInjectionUtils {

private static final Logger log = LoggerFactory.getLogger(SqlInjectionUtils.class);

/**
* SQL语法检查正则:符合两个关键字(有先后顺序)才算匹配
*/
Expand All @@ -39,15 +46,83 @@ public class SqlInjectionUtils {
private static final Pattern SQL_COMMENT_PATTERN = Pattern
.compile("'.*(or|union|--|#|/\\*|;)", Pattern.CASE_INSENSITIVE);

/**
* SQL 语法关键字
*/
private static final String SQL_SYNTAX_KEYWORD = "and |exec |peformance_schema|information_schema|extractvalue|updatexml|geohash|gtid_subset|gtid_subtract|insert |select |delete |update |drop |count |chr |mid |master |truncate |char |declare |;|or |+|--";

/**
* SQL 函数检查正则
*/
private static final String[] SQL_FUNCTION_PATTERN = new String[] {"chr\\s*\\(", "mid\\s*\\(", " char\\s*\\(",
"sleep\\s*\\(", "user\\s*\\(", "show\\s+tables", "user[\\s]*\\([\\s]*\\)", "show\\s+databases",
"sleep\\(\\d*\\)", "sleep\\(.*\\)",};

private static final String MESSAGE_TEMPLATE = "SQL 注入检查: 检查值=>{}<=存在 SQL 注入关键字, 关键字=>{}<=";

private SqlInjectionUtils() {
}

/**
* 检查参数是否存在 SQL 注入
*
* @param value 检查参数
* @return true:非法;false:合法
*/
public static boolean check(String value) {
Objects.requireNonNull(value);
// 处理是否包含 SQL 注释字符 || 检查是否包含 SQ L注入敏感字符
return SQL_COMMENT_PATTERN.matcher(value).find() || SQL_SYNTAX_PATTERN.matcher(value).find();
return check(value, null);
}

/**
* 检查参数是否存在 SQL 注入
*
* @param value 检查参数
* @param customKeyword 自定义关键字
* @return true:非法;false:合法
*/
public static boolean check(String value, String customKeyword) {
if (CharSequenceUtil.isBlank(value)) {
return false;
}
// 处理是否包含 SQL 注释字符 || 检查是否包含 SQL 注入敏感字符
if (SQL_COMMENT_PATTERN.matcher(value).find() || SQL_SYNTAX_PATTERN.matcher(value).find()) {
log.warn("SQL 注入检查: 检查值=>{}<=存在 SQL 注释字符或 SQL 注入敏感字符", value);
return true;
}
// 转换成小写再进行比较
value = value.toLowerCase().trim();
// 检查是否包含 SQL 语法关键字
if (checkKeyword(value, SQL_SYNTAX_KEYWORD.split("\\|"))) {
return true;
}
// 检查是否包含自定义关键字
if (CharSequenceUtil.isNotBlank(customKeyword) && checkKeyword(value, customKeyword.split("\\|"))) {
return true;
}
// 检查是否包含 SQL 注入敏感字符
for (String pattern : SQL_FUNCTION_PATTERN) {
if (Pattern.matches(".*" + pattern + ".*", value)) {
log.warn(MESSAGE_TEMPLATE, value, pattern);
return true;
}
}
return false;
}

/**
* 检查参数是否存在关键字
*
* @param value 检查参数
* @param keywords 关键字列表
* @return true:非法;false:合法
*/
private static boolean checkKeyword(String value, String[] keywords) {
for (String keyword : keywords) {
if (value.contains(keyword)) {
log.warn(MESSAGE_TEMPLATE, value, keyword);
return true;
}
}
return false;
}
}

0 comments on commit 22ebdfe

Please sign in to comment.