From ddf0f61ae59d217b59884921a98a0bc69b143f41 Mon Sep 17 00:00:00 2001 From: JEECG <445654970@qq.com> Date: Tue, 27 May 2025 18:40:34 +0800 Subject: [PATCH] =?UTF-8?q?=E4=BF=AE=E5=A4=8Dv3.8.0=20=E5=AD=98=E5=9C=A8?= =?UTF-8?q?=E7=BB=95=E8=BF=87sql=E9=BB=91=E5=90=8D=E5=8D=95=E9=99=90?= =?UTF-8?q?=E5=88=B6sql=E6=B3=A8=E5=85=A5=E6=BC=8F=E6=B4=9E=20#8335=20?= =?UTF-8?q?=E4=BF=AE=E5=A4=8Dminidao=20`getQueryTableInfo`=E6=97=A0?= =?UTF-8?q?=E6=B3=95=E8=A7=A3=E6=9E=90=E5=B8=A6=E6=8B=AC=E5=8F=B7=E7=9A=84?= =?UTF-8?q?=E8=A1=A8=E5=90=8D=E3=80=81=E5=A2=9E=E5=8A=A0=E6=95=B0=E6=8D=AE?= =?UTF-8?q?=E5=BA=93=E5=90=8D=E8=A7=A3=E6=9E=90=E8=83=BD=E5=8A=9B?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../jeecg/common/util/SqlInjectionUtil.java | 48 ++++++++++++++++++- .../AbstractQueryBlackListHandler.java | 24 ++++++++++ jeecg-boot/pom.xml | 2 +- 3 files changed, 71 insertions(+), 3 deletions(-) diff --git a/jeecg-boot/jeecg-boot-base-core/src/main/java/org/jeecg/common/util/SqlInjectionUtil.java b/jeecg-boot/jeecg-boot-base-core/src/main/java/org/jeecg/common/util/SqlInjectionUtil.java index c11c62e9b..853551c27 100644 --- a/jeecg-boot/jeecg-boot-base-core/src/main/java/org/jeecg/common/util/SqlInjectionUtil.java +++ b/jeecg-boot/jeecg-boot-base-core/src/main/java/org/jeecg/common/util/SqlInjectionUtil.java @@ -5,6 +5,7 @@ import lombok.extern.slf4j.Slf4j; import org.jeecg.common.constant.CommonConstant; import org.jeecg.common.constant.SymbolConstant; import org.jeecg.common.exception.JeecgSqlInjectionException; + import java.util.ArrayList; import java.util.List; import java.util.regex.Matcher; @@ -16,7 +17,13 @@ import java.util.regex.Pattern; * @author zhoujf */ @Slf4j -public class SqlInjectionUtil { +public class SqlInjectionUtil { + + /** + * sql注入黑名单数据库名 + */ + public final static String XSS_STR_TABLE = "peformance_schema|information_schema"; + /** * 默认—sql注入关键词 */ @@ -167,7 +174,28 @@ public class SqlInjectionUtil { } return false; } - + + /** + * 判断是否存在SQL注入关键词字符串 + * + * @param keyword + * @return + */ + @SuppressWarnings("AlibabaUndefineMagicConstant") + private static boolean isExistSqlInjectTableKeyword(String sql, String keyword) { + // 需要匹配的,sql注入关键词 + String[] matchingTexts = new String[]{"`" + keyword, "(" + keyword, "(`" + keyword}; + for (String matchingText : matchingTexts) { + String[] checkTexts = new String[]{" " + matchingText, "from" + matchingText}; + for (String checkText : checkTexts) { + if (sql.contains(checkText)) { + return true; + } + } + } + return false; + } + /** * sql注入过滤处理,遇到注入关键字抛异常 * @@ -208,6 +236,14 @@ public class SqlInjectionUtil { throw new JeecgSqlInjectionException(SqlInjectionUtil.SQL_INJECTION_TIP + value); } } + String[] xssTableArr = XSS_STR_TABLE.split("\\|"); + for (String xssTableStr : xssTableArr) { + if (isExistSqlInjectTableKeyword(value, xssTableStr)) { + log.error(SqlInjectionUtil.SQL_INJECTION_KEYWORD_TIP, xssTableStr); + log.error(SqlInjectionUtil.SQL_INJECTION_TIP_VARIABLE, value); + throw new JeecgSqlInjectionException(SqlInjectionUtil.SQL_INJECTION_TIP + value); + } + } // 三、SQL注入检测存在绕过风险 (正则校验) for (String regularOriginal : XSS_REGULAR_STR_ARRAY) { @@ -244,6 +280,14 @@ public class SqlInjectionUtil { throw new JeecgSqlInjectionException(SqlInjectionUtil.SQL_INJECTION_TIP + value); } } + String[] xssTableArr = XSS_STR_TABLE.split("\\|"); + for (String xssTableStr : xssTableArr) { + if (isExistSqlInjectTableKeyword(value, xssTableStr)) { + log.error(SqlInjectionUtil.SQL_INJECTION_KEYWORD_TIP, xssTableStr); + log.error(SqlInjectionUtil.SQL_INJECTION_TIP_VARIABLE, value); + throw new JeecgSqlInjectionException(SqlInjectionUtil.SQL_INJECTION_TIP + value); + } + } // 三、SQL注入检测存在绕过风险 (正则校验) for (String regularOriginal : XSS_REGULAR_STR_ARRAY) { diff --git a/jeecg-boot/jeecg-boot-base-core/src/main/java/org/jeecg/common/util/security/AbstractQueryBlackListHandler.java b/jeecg-boot/jeecg-boot-base-core/src/main/java/org/jeecg/common/util/security/AbstractQueryBlackListHandler.java index 8b7e5e26f..0e384bb76 100644 --- a/jeecg-boot/jeecg-boot-base-core/src/main/java/org/jeecg/common/util/security/AbstractQueryBlackListHandler.java +++ b/jeecg-boot/jeecg-boot-base-core/src/main/java/org/jeecg/common/util/security/AbstractQueryBlackListHandler.java @@ -3,6 +3,8 @@ package org.jeecg.common.util.security; import lombok.extern.slf4j.Slf4j; import org.apache.commons.lang.StringUtils; import org.jeecg.common.exception.JeecgSqlInjectionException; +import org.jeecg.common.util.SqlInjectionUtil; +import org.jeecg.common.util.oConvertUtils; import java.util.*; import java.util.regex.Matcher; @@ -66,6 +68,8 @@ public abstract class AbstractQueryBlackListHandler { if(flag == false){ return false; } + Set xssTableSet = new HashSet<>(Arrays.asList(SqlInjectionUtil.XSS_STR_TABLE.split("\\|"))); + for (QueryTable table : list) { String name = table.getName(); String fieldRule = ruleMap.get(name); @@ -81,6 +85,16 @@ public abstract class AbstractQueryBlackListHandler { } } + // 判断是否调用了黑名单数据库 + String dbName = table.getDbName(); + if (oConvertUtils.isNotEmpty(dbName)) { + dbName = dbName.toLowerCase().trim(); + if (xssTableSet.contains(dbName)) { + flag = false; + log.warn("sql黑名单校验,数据库【" + dbName + "】禁止查询"); + break; + } + } } // 返回黑名单校验结果(不合法直接抛出异常) @@ -135,6 +149,8 @@ public abstract class AbstractQueryBlackListHandler { * 查询的表的信息 */ protected class QueryTable { + //数据库名 + private String dbName; //表名 private String name; //表的别名 @@ -158,6 +174,14 @@ public abstract class AbstractQueryBlackListHandler { this.fields.add(field); } + public String getDbName() { + return dbName; + } + + public void setDbName(String dbName) { + this.dbName = dbName; + } + public String getName() { return name; } diff --git a/jeecg-boot/pom.xml b/jeecg-boot/pom.xml index 17dc0fd02..6dbfead83 100644 --- a/jeecg-boot/pom.xml +++ b/jeecg-boot/pom.xml @@ -57,7 +57,7 @@ 1.9.5.1 - 1.10.7 + 1.10.10 3.5.3.2 4.1.3