Explorar o código

fix: parameterize JSON_EXTRACT dimension_weights queries to prevent SQL injection

Replace string concatenation with MyBatis parameter binding via CONCAT('$.', {0})
- ArticleService.getList() / getFeatured()
- ProductService.getProductPage()
- TaskService dimension filter
- ActivityService dimension filter
Xiaogang Liao hai 1 mes
pai
achega
4ecff23989

+ 1 - 1
cfc-backend/src/main/java/com/etotem/cfc/service/ActivityService.java

@@ -57,7 +57,7 @@ public class ActivityService extends ServiceImpl<ActivityMapper, Activity> {
         if (dimensionCode != null && !dimensionCode.isEmpty()) {
             // P1: 权重感知查询 — 匹配 dimension_weights > 0 或兼容旧版 dimension_code
             query.and(w -> w
-                .apply("COALESCE(JSON_EXTRACT(dimension_weights, '$." + dimensionCode + "'), 0) > 0")
+                .apply("COALESCE(JSON_EXTRACT(dimension_weights, CONCAT('$.', {0})), 0) > 0", dimensionCode)
                 .or().eq(Activity::getDimensionCode, dimensionCode)
             );
         }

+ 6 - 4
cfc-backend/src/main/java/com/etotem/cfc/service/ArticleService.java

@@ -91,10 +91,11 @@ public class ArticleService {
             wrapper.like(Article::getTitle, keyword.trim());
         }
         if (dimensionCode != null && !dimensionCode.trim().isEmpty()) {
+            String dim = dimensionCode.trim();
             // P1: 权重感知查询 — 匹配 dimension_weights > 0 或兼容旧版 relatedDimensions
             wrapper.and(w -> w
-                .apply("COALESCE(JSON_EXTRACT(dimension_weights, '$." + dimensionCode.trim() + "'), 0) > 0")
-                .or().like(Article::getRelatedDimensions, dimensionCode.trim())
+                .apply("COALESCE(JSON_EXTRACT(dimension_weights, CONCAT('$.', {0})), 0) > 0", dim)
+                .or().like(Article::getRelatedDimensions, dim)
             );
         }
 
@@ -122,10 +123,11 @@ public class ArticleService {
                 .last("LIMIT " + Math.max(size, 50));
 
         if (dimensionCode != null && !dimensionCode.trim().isEmpty()) {
+            String dim = dimensionCode.trim();
             // P1: 权重感知查询 — 匹配 dimension_weights > 0 或兼容旧版 relatedDimensions
             wrapper.and(w -> w
-                .apply("COALESCE(JSON_EXTRACT(dimension_weights, '$." + dimensionCode.trim() + "'), 0) > 0")
-                .or().like(Article::getRelatedDimensions, dimensionCode.trim())
+                .apply("COALESCE(JSON_EXTRACT(dimension_weights, CONCAT('$.', {0})), 0) > 0", dim)
+                .or().like(Article::getRelatedDimensions, dim)
             );
         }
 

+ 1 - 1
cfc-backend/src/main/java/com/etotem/cfc/service/ProductService.java

@@ -58,7 +58,7 @@ public class ProductService {
         if (dimCode != null && !dimCode.isEmpty()) {
             // P1: 权重感知查询 — 匹配 dimension_weights > 0 或兼容旧版 domain
             wrapper.and(w -> w
-                .apply("COALESCE(JSON_EXTRACT(dimension_weights, '$." + dimCode + "'), 0) > 0")
+                .apply("COALESCE(JSON_EXTRACT(dimension_weights, CONCAT('$.', {0})), 0) > 0", dimCode)
                 .or().eq(Product::getDomain, dimCode)
             );
         }

+ 1 - 1
cfc-backend/src/main/java/com/etotem/cfc/service/TaskService.java

@@ -228,7 +228,7 @@ public List<Task> getTodayTasks(Long childId, String dimensionCode) {
 
         if (dimensionCode != null && !dimensionCode.isEmpty()) {
             wrapper.and(w -> w
-                .apply("COALESCE(JSON_EXTRACT(dimension_weights, '$." + dimensionCode + "'), 0) > 0")
+                .apply("COALESCE(JSON_EXTRACT(dimension_weights, CONCAT('$.', {0})), 0) > 0", dimensionCode)
                 .or().eq(Task::getDimensionCode, dimensionCode)
             );
         }