From 293323ff6acca39161e9007a0eb805f5c36d9838 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E8=B0=AD=E5=87=AF=E5=87=AF?= Date: Wed, 12 Feb 2025 10:46:27 +0800 Subject: [PATCH] =?UTF-8?q?=E8=84=9A=E6=89=8B=E6=9E=B6=E5=AE=8C=E5=96=84?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../src/main/java/com/czg/utils/SqlUtil.java | 37 ++++++++++++------- 1 file changed, 23 insertions(+), 14 deletions(-) diff --git a/cash-common/cash-common-tools/src/main/java/com/czg/utils/SqlUtil.java b/cash-common/cash-common-tools/src/main/java/com/czg/utils/SqlUtil.java index 937231ce..239ba119 100644 --- a/cash-common/cash-common-tools/src/main/java/com/czg/utils/SqlUtil.java +++ b/cash-common/cash-common-tools/src/main/java/com/czg/utils/SqlUtil.java @@ -1,6 +1,8 @@ package com.czg.utils; import cn.hutool.core.util.StrUtil; + +import java.util.Objects; import java.util.regex.Pattern; /** @@ -10,14 +12,15 @@ import java.util.regex.Pattern; */ public class SqlUtil { /** - * 定义常用的 sql关键字 + * SQL语法检查正则:符合两个关键字(有先后顺序)才算匹配 */ - private static final Pattern SQL_KEYWORD_PATTERN = Pattern.compile("(?i)(and |extractvalue|updatexml|exec |insert |select |delete |update |drop |count |chr |mid |master |truncate |char |declare |or |\\+|user\\(\\))"); - + 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+)" + + "|if\\s*\\(.*\\)|select\\s*\\(.*\\)|substr\\s*\\(.*\\)|substring\\s*\\(.*\\)|char\\s*\\(.*\\)|concat\\s*\\(.*\\)|benchmark\\s*\\(.*\\)|sleep\\s*\\(.*\\)|(and|or)\\s+.*", Pattern.CASE_INSENSITIVE); /** - * 仅支持字母、数字、下划线、空格、逗号、小数点(支持多个字段排序) + * 使用'、;或注释截断SQL检查正则 */ - private static final Pattern SQL_PATTERN = Pattern.compile("[a-zA-Z0-9_\\ \\,\\.]+"); + private static final Pattern SQL_COMMENT_PATTERN = Pattern.compile("'.*(or|union|--|#|/\\*|;)", Pattern.CASE_INSENSITIVE); /** * 限制orderBy最大长度 @@ -29,7 +32,7 @@ public class SqlUtil { */ public static String escapeOrderBySql(String value) { if (StrUtil.isNotEmpty(value)) { - if (!isValidOrderBySql(value)) { + if (!check(value)) { throw new IllegalArgumentException("参数不符合规范,不能进行查询"); } if (value.length() > ORDER_BY_MAX_LENGTH) { @@ -40,18 +43,24 @@ public class SqlUtil { } /** - * 验证 order by 语法是否符合规范 + * 检查参数是否存在 SQL 注入 + * + * @param value 检查参数 + * @return true 非法 false 合法 */ - public static boolean isValidOrderBySql(String value) { - return SQL_PATTERN.matcher(value).matches(); + public static boolean check(String value) { + Objects.requireNonNull(value); + // 处理是否包含SQL注释字符 || 检查是否包含SQL注入敏感字符 + return SQL_COMMENT_PATTERN.matcher(value).find() || SQL_SYNTAX_PATTERN.matcher(value).find(); } /** - * SQL关键字检查 + * 刪除字段转义符单引号双引号 + * + * @param text 待处理字段 */ - public static void filterKeyword(String value) { - if (StrUtil.isNotEmpty(value) && SQL_KEYWORD_PATTERN.matcher(value).find()) { - throw new IllegalArgumentException("参数存在 SQL 注入风险"); - } + public static String removeEscapeCharacter(String text) { + Objects.nonNull(text); + return text.replaceAll("\"", "").replaceAll("'", ""); } }