--重构表字典逻辑,深度解决SQL注入漏洞问题(修复导致的bug修复)--

pull/5377/head
zhangdaiscott 1 year ago
parent 44952c79c2
commit 473875a9d2

@ -6,6 +6,7 @@ import com.baomidou.dynamic.datasource.spring.boot.autoconfigure.DynamicDataSour
import com.baomidou.mybatisplus.annotation.DbType; import com.baomidou.mybatisplus.annotation.DbType;
import com.baomidou.mybatisplus.extension.toolkit.JdbcUtils; import com.baomidou.mybatisplus.extension.toolkit.JdbcUtils;
import lombok.extern.slf4j.Slf4j; import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang.StringUtils;
import org.jeecg.common.constant.CommonConstant; import org.jeecg.common.constant.CommonConstant;
import org.jeecg.common.constant.DataBaseConstant; import org.jeecg.common.constant.DataBaseConstant;
import org.jeecg.common.constant.ServiceNameConstants; import org.jeecg.common.constant.ServiceNameConstants;
@ -26,6 +27,7 @@ import java.io.InputStream;
import java.sql.Connection; import java.sql.Connection;
import java.sql.DatabaseMetaData; import java.sql.DatabaseMetaData;
import java.sql.SQLException; import java.sql.SQLException;
import java.util.List;
import java.util.Map; import java.util.Map;
import java.util.regex.Matcher; import java.util.regex.Matcher;
import java.util.regex.Pattern; import java.util.regex.Pattern;
@ -145,7 +147,7 @@ public class CommonUtils {
* @param bizPath * @param bizPath
* @return * @return
*/ */
public static String uploadLocal(MultipartFile mf,String bizPath,String uploadpath){ public static String uploadLocal(MultipartFile mf, String bizPath, String uploadpath){
try { try {
//update-begin-author:liusq date:20210809 for: 过滤上传文件类型 //update-begin-author:liusq date:20210809 for: 过滤上传文件类型
FileTypeFilter.fileTypeFilter(mf); FileTypeFilter.fileTypeFilter(mf);
@ -272,7 +274,7 @@ public class CommonUtils {
if(db==null){ if(db==null){
return null; return null;
} }
DriverManagerDataSource ds = new DriverManagerDataSource (); DriverManagerDataSource ds = new DriverManagerDataSource();
ds.setDriverClassName(db.getDriverClassName()); ds.setDriverClassName(db.getDriverClassName());
ds.setUrl(db.getUrl()); ds.setUrl(db.getUrl());
ds.setUsername(db.getUsername()); ds.setUsername(db.getUsername());
@ -392,4 +394,47 @@ public class CommonUtils {
return target; return target;
} }
/**
* list
* @param list String
* @param separator
* @return
*/
public static String getSplitText(List<String> list, String separator) {
if (null != list && list.size() > 0) {
return StringUtils.join(list, separator);
}
return "";
}
/**
* tableSQL
*
* @param tableSql sys_user where name = '1212'
* @return name = '1212'
*/
public static String getFilterSqlByTableSql(String tableSql) {
if (tableSql.toLowerCase().indexOf(DataBaseConstant.SQL_WHERE) > 0) {
String[] arr = tableSql.split(" (?i)where ");
if (arr != null && oConvertUtils.isNotEmpty(arr[1])) {
return arr[1];
}
}
return "";
}
/**
* table
*
* @param tableSql sys_user where name = '1212'
* @return sys_user
*/
public static String getTableNameByTableSql(String tableSql) {
if (tableSql.toLowerCase().indexOf(DataBaseConstant.SQL_WHERE) > 0) {
String[] arr = tableSql.split(" (?i)where ");
return arr[0].trim();
} else {
return tableSql;
}
}
} }

@ -18,6 +18,7 @@ import org.jeecg.common.system.util.ResourceUtil;
import org.jeecg.common.system.vo.DictModel; import org.jeecg.common.system.vo.DictModel;
import org.jeecg.common.system.vo.DictModelMany; import org.jeecg.common.system.vo.DictModelMany;
import org.jeecg.common.system.vo.DictQuery; import org.jeecg.common.system.vo.DictQuery;
import org.jeecg.common.util.CommonUtils;
import org.jeecg.common.util.SqlInjectionUtil; import org.jeecg.common.util.SqlInjectionUtil;
import org.jeecg.common.util.oConvertUtils; import org.jeecg.common.util.oConvertUtils;
import org.jeecg.config.mybatis.MybatisPlusSaasConfig; import org.jeecg.config.mybatis.MybatisPlusSaasConfig;
@ -456,18 +457,18 @@ public class SysDictServiceImpl extends ServiceImpl<SysDictMapper, SysDict> impl
// } // }
@Override @Override
public List<DictModel> queryLittleTableDictItems(String table, String text, String code, String condition, String keyword, int pageSize) { public List<DictModel> queryLittleTableDictItems(String tableSql, String text, String code, String condition, String keyword, int pageSize) {
Page<DictModel> page = new Page<DictModel>(1, pageSize); Page<DictModel> page = new Page<DictModel>(1, pageSize);
page.setSearchCount(false); page.setSearchCount(false);
//为了防止sqljeecg提供了防注入的方法可以在拼接 SQL 语句时自动对参数进行转义避免SQL注入攻击 //为了防止sqljeecg提供了防注入的方法可以在拼接 SQL 语句时自动对参数进行转义避免SQL注入攻击
// 1. 针对采用 ${}写法的表名和字段进行转义和check // 1. 针对采用 ${}写法的表名和字段进行转义和check
table = SqlInjectionUtil.getSqlInjectTableName(table); String table = SqlInjectionUtil.getSqlInjectTableName(CommonUtils.getTableNameByTableSql(tableSql));
text = SqlInjectionUtil.getSqlInjectField(text); text = SqlInjectionUtil.getSqlInjectField(text);
code = SqlInjectionUtil.getSqlInjectField(code); code = SqlInjectionUtil.getSqlInjectField(code);
// 2. 查询条件SQL (获取条件sql方法含sql注入校验) // 2. 查询条件SQL (获取条件sql方法含sql注入校验)
String filterSql = getFilterSql(table, text, code, condition, keyword); String filterSql = getFilterSql(tableSql, text, code, condition, keyword);
// 3. 返回表字典数据 // 3. 返回表字典数据
IPage<DictModel> pageList = baseMapper.queryPageTableDictWithFilter(page, table, text, code, filterSql); IPage<DictModel> pageList = baseMapper.queryPageTableDictWithFilter(page, table, text, code, filterSql);
@ -475,21 +476,22 @@ public class SysDictServiceImpl extends ServiceImpl<SysDictMapper, SysDict> impl
} }
/** /**
* * ( )
*
* @param text * @param text
* @param code * @param code
* @param condition * @param condition
* @param keyword * @param keyword
* @return * @return
*/ */
private String getFilterSql(String table, String text, String code, String condition, String keyword){ private String getFilterSql(String tableSql, String text, String code, String condition, String keyword){
String filterSql = ""; String filterSql = "";
String keywordSql = null; String keywordSql = null;
String sqlWhere = "where "; String sqlWhere = "where ";
//【JTC-631】判断如果 table 携带了 where 条件,那么就使用 and 查询,防止报错 //【JTC-631】判断如果 table 携带了 where 条件,那么就使用 and 查询,防止报错
if (table.toLowerCase().contains(sqlWhere)) { if (tableSql.toLowerCase().contains(sqlWhere)) {
sqlWhere = " and "; sqlWhere = CommonUtils.getFilterSqlByTableSql(tableSql) + " and ";
} }
// 下拉搜索组件 支持传入排序信息 查询排序 // 下拉搜索组件 支持传入排序信息 查询排序
@ -532,13 +534,16 @@ public class SysDictServiceImpl extends ServiceImpl<SysDictMapper, SysDict> impl
filterSql += " order by " + orderField + " " + orderType; filterSql += " order by " + orderField + " " + orderType;
} }
// result.1 返回条件SQL去掉 where 关键词) // 处理返回条件
final String wherePattern = "(?i)where "; // (?i) 表示不区分大小写 // 1.1 返回条件SQL去掉开头的 where
String filterSqlString = filterSql.trim().replaceAll(wherePattern, ""); final String wherePrefix = "(?i)where "; // (?i) 表示不区分大小写
String filterSqlString = filterSql.trim().replaceAll(wherePrefix, "");
// result.2 条件SQL进行漏洞 check // 1.2 条件SQL进行漏洞 check
SqlInjectionUtil.specialFilterContentForDictSql(filterSqlString); SqlInjectionUtil.specialFilterContentForDictSql(filterSqlString);
// 1.3 判断如何返回条件是 order by开头则前面拼上 1=1
if (oConvertUtils.isNotEmpty(filterSqlString) && filterSqlString.trim().toUpperCase().startsWith("ORDER")) {
filterSqlString = " 1=1 " + filterSqlString;
}
return filterSqlString; return filterSqlString;
} }

Loading…
Cancel
Save