diff --git a/framework/src/main/java/cn/lili/modules/search/serviceimpl/EsGoodsSearchServiceImpl.java b/framework/src/main/java/cn/lili/modules/search/serviceimpl/EsGoodsSearchServiceImpl.java index 330f17ed..6b0cb37a 100644 --- a/framework/src/main/java/cn/lili/modules/search/serviceimpl/EsGoodsSearchServiceImpl.java +++ b/framework/src/main/java/cn/lili/modules/search/serviceimpl/EsGoodsSearchServiceImpl.java @@ -15,6 +15,7 @@ import cn.lili.modules.search.entity.dto.EsGoodsSearchDTO; import cn.lili.modules.search.entity.dto.ParamOptions; import cn.lili.modules.search.entity.dto.SelectorOptions; import cn.lili.modules.search.service.EsGoodsSearchService; +import cn.lili.modules.search.utils.SqlFilter; import com.alibaba.druid.util.StringUtils; import lombok.extern.slf4j.Slf4j; import org.apache.lucene.search.join.ScoreMode; @@ -81,7 +82,10 @@ public class EsGoodsSearchServiceImpl implements EsGoodsSearchService { @Override public SearchPage searchGoods(EsGoodsSearchDTO searchDTO, PageVO pageVo) { - if (CharSequenceUtil.isNotBlank(searchDTO.getKeyword())) { + + //如果搜索词不为空,且明显不是sql注入,那么就将搜索词加入热搜词 + //PS:线上环境运行很多客户反馈被sql攻击,写在了搜索热词里,这里控制命中关键字就不做热词统计,如果线上比较严格可以调用关键词替换,不过不建议这么做 + if (CharSequenceUtil.isNotBlank(searchDTO.getKeyword()) && !SqlFilter.hit(searchDTO.getKeyword())) { cache.incrementScore(CachePrefix.HOT_WORD.getPrefix(), searchDTO.getKeyword()); } NativeSearchQueryBuilder searchQueryBuilder = createSearchQueryBuilder(searchDTO, pageVo); diff --git a/framework/src/main/java/cn/lili/modules/search/utils/SqlFilter.java b/framework/src/main/java/cn/lili/modules/search/utils/SqlFilter.java new file mode 100644 index 00000000..f1a2d374 --- /dev/null +++ b/framework/src/main/java/cn/lili/modules/search/utils/SqlFilter.java @@ -0,0 +1,59 @@ +package cn.lili.modules.search.utils; + +import java.util.Arrays; +import java.util.HashSet; +import java.util.Set; + +/** + * sql 关键字过滤 + * + * @author liushuai(liushuai711 @ gmail.com) + * @version v4.0 + * @Description: + * @since 2023/3/22 17:27 + */ + +public class SqlFilter { + + private static final Set SQL_KEYWORDS = new HashSet<>(Arrays.asList( + "SELECT", "FROM", "WHERE", "AND", "OR", "NOT", "INSERT", "UPDATE", "DELETE", "CREATE", + "TABLE", "INDEX", "VIEW", "DROP", "ALTER", "COLUMN", "ADD", "SET", "GROUP", "BY", + "HAVING", "ORDER", "ASC", "DESC", "LIKE", "IN", "BETWEEN", "IS", "NULL", "TRUE", "FALSE", + "JOIN", "LEFT", "RIGHT", "INNER", "OUTER", "FULL", "ON", "AS", "DISTINCT", "COUNT", + "MAX", "MIN", "SUM", "AVG" + )); + + + /** + * 关键字命中 + * + * @param sql + * @return + */ + public static Boolean hit(String sql) { + String[] tokens = sql.split("\\s+"); + for (String token : tokens) { + if (!SQL_KEYWORDS.contains(token.toUpperCase())) { + return true; + } + } + return false; + } + + /** + * 关键字替换 + * + * @param sql + * @return + */ + public static String filterSql(String sql) { + String[] tokens = sql.split("\\s+"); + StringBuilder filteredSql = new StringBuilder(); + for (String token : tokens) { + if (!SQL_KEYWORDS.contains(token.toUpperCase())) { + filteredSql.append(token).append(" "); + } + } + return filteredSql.toString().trim(); + } +}