From 61adedf9020ba378846c0945fa9f7607c8314ef7 Mon Sep 17 00:00:00 2001 From: PIGCLOUD Date: Mon, 9 Mar 2026 10:46:07 +0800 Subject: [PATCH] =?UTF-8?q?fix(pigx-common-data):=20=E6=B7=BB=E5=8A=A0=20S?= =?UTF-8?q?QL=20=E6=B3=A8=E5=85=A5=E6=A3=80=E6=9F=A5=E5=B9=B6=E7=A7=BB?= =?UTF-8?q?=E9=99=A4=E8=87=AA=E5=AE=9A=E4=B9=89=E8=BD=AC=E4=B9=89=E6=96=B9?= =?UTF-8?q?=E6=B3=95?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit - 在数据权限拦截器中添加 SQL 注入检查,使用 MyBatis-Plus 的 SqlInjectionUtils 工具类 - 移除原有的 escapeSql 自定义转义方法,直接使用原始 username 参数 - 在生成条件表达式和查询语句时增加注入检查逻辑,发现注入风险时返回空结果集 --- .../datascope/DataScopeInnerInterceptor.java | 29 ++++++++++--------- 1 file changed, 15 insertions(+), 14 deletions(-) diff --git a/pigx-common/pigx-common-data/src/main/java/com/pig4cloud/pigx/common/data/datascope/DataScopeInnerInterceptor.java b/pigx-common/pigx-common-data/src/main/java/com/pig4cloud/pigx/common/data/datascope/DataScopeInnerInterceptor.java index c791cf28d..dbb3f51b2 100644 --- a/pigx-common/pigx-common-data/src/main/java/com/pig4cloud/pigx/common/data/datascope/DataScopeInnerInterceptor.java +++ b/pigx-common/pigx-common-data/src/main/java/com/pig4cloud/pigx/common/data/datascope/DataScopeInnerInterceptor.java @@ -4,6 +4,7 @@ import cn.hutool.core.collection.CollUtil; import cn.hutool.core.collection.CollectionUtil; import cn.hutool.core.util.StrUtil; import com.baomidou.mybatisplus.core.toolkit.PluginUtils; +import com.baomidou.mybatisplus.core.toolkit.sql.SqlInjectionUtils; import lombok.Setter; import lombok.extern.slf4j.Slf4j; import net.sf.jsqlparser.JSQLParserException; @@ -128,19 +129,24 @@ public class DataScopeInnerInterceptor implements DataScopeInterceptor { return CCJSqlParserUtil.parseCondExpression("1 = 2"); } + // SQL 注入检查 + if (StrUtil.isNotBlank(username) && SqlInjectionUtils.check(username)) { + return CCJSqlParserUtil.parseCondExpression("1 = 2"); + } + // 2. 本人权限 + 部门权限:加括号保证与原有条件组合时的优先级 if (StrUtil.isNotBlank(username) && CollUtil.isNotEmpty(deptIds)) { String join = CollectionUtil.join(deptIds, ","); String logicKeyword = dataScope.getLogicMode() != null ? dataScope.getLogicMode().getKeyword() : DataScopeLogicEnum.OR.getKeyword(); String condSql = String.format("(%s%s = '%s' %s %s%s IN (%s))", prefix, dataScope.getScopeUserName(), - escapeSql(username), logicKeyword, prefix, dataScope.getScopeDeptName(), join); + username, logicKeyword, prefix, dataScope.getScopeDeptName(), join); return CCJSqlParserUtil.parseCondExpression(condSql); } // 3. 仅本人权限 if (StrUtil.isNotBlank(username)) { - String condSql = String.format("%s%s = '%s'", prefix, dataScope.getScopeUserName(), escapeSql(username)); + String condSql = String.format("%s%s = '%s'", prefix, dataScope.getScopeUserName(), username); return CCJSqlParserUtil.parseCondExpression(condSql); } @@ -182,6 +188,11 @@ public class DataScopeInnerInterceptor implements DataScopeInterceptor { return String.format("SELECT %s FROM (%s) temp_data_scope WHERE 1 = 2", selectType, originalSql); } + // SQL 注入检查 + if (StrUtil.isNotBlank(username) && SqlInjectionUtils.check(username)) { + return String.format("SELECT %s FROM (%s) temp_data_scope WHERE 1 = 2", selectType, originalSql); + } + // 本人 + 部门 if (StrUtil.isNotBlank(username) && CollUtil.isNotEmpty(deptIds)) { String join = CollectionUtil.join(deptIds, ","); @@ -189,14 +200,14 @@ public class DataScopeInnerInterceptor implements DataScopeInterceptor { : DataScopeLogicEnum.OR.getKeyword(); return String.format( "SELECT %s FROM (%s) temp_data_scope WHERE (temp_data_scope.%s = '%s' %s temp_data_scope.%s IN (%s))", - selectType, originalSql, dataScope.getScopeUserName(), escapeSql(username), logicKeyword, + selectType, originalSql, dataScope.getScopeUserName(), username, logicKeyword, dataScope.getScopeDeptName(), join); } // 仅本人 if (StrUtil.isNotBlank(username)) { return String.format("SELECT %s FROM (%s) temp_data_scope WHERE temp_data_scope.%s = '%s'", selectType, - originalSql, dataScope.getScopeUserName(), escapeSql(username)); + originalSql, dataScope.getScopeUserName(), username); } // 仅部门 @@ -205,16 +216,6 @@ public class DataScopeInnerInterceptor implements DataScopeInterceptor { originalSql, dataScope.getScopeDeptName(), join); } - /** - * 转义 SQL 字符串值中的单引号,防止 SQL 注入 - */ - private String escapeSql(String value) { - if (value == null) { - return ""; - } - return value.replace("'", "''"); - } - /** * 查找参数是否包括DataScope对象 *