mirror of
https://gitcode.com/ageerle/ruoyi-ai.git
synced 2026-09-13 00:14:59 +00:00
fix: 移除FastJson 1.2.83严重安全漏洞,替换为Jackson
- 移除FastJson 1.2.83依赖(存在严重RCE漏洞CVE-2022-25845等) - 替换为Spring Boot内置的Jackson 2.18.2 - 修改6个Java文件的JSON处理逻辑 - 所有模块编译验证通过 修改文件: 1. pom.xml - 移除fastjson依赖定义 2. ruoyi-common-chat/pom.xml - 替换为jackson-databind 3. QwenFileUploadUtils.java - 千问文件上传JSON解析 4. ChatRequest.java - 移除FastJson注解 5. MailSendNode.java - 邮件节点JSON处理 6. SwitcherNode.java - 条件分支JSON处理 7. AbstractAuthWeChatEnterpriseRequest.java - 企业微信登录 8. AuthDingTalkV2Request.java - 钉钉登录 安全提升:消除FastJson反序列化RCE漏洞攻击面 Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
This commit is contained in:
@@ -1,8 +1,7 @@
|
||||
package org.ruoyi.workflow.workflow.node.mailSend;
|
||||
|
||||
import com.alibaba.fastjson.JSON;
|
||||
import com.alibaba.fastjson.JSONObject;
|
||||
import com.alibaba.fastjson.JSONValidator;
|
||||
import com.fasterxml.jackson.databind.JsonNode;
|
||||
import com.fasterxml.jackson.databind.ObjectMapper;
|
||||
import jakarta.mail.internet.MimeMessage;
|
||||
import lombok.extern.slf4j.Slf4j;
|
||||
import org.apache.commons.lang3.StringUtils;
|
||||
@@ -41,10 +40,15 @@ public class MailSendNode extends AbstractWfNode {
|
||||
String input = getDataFromInput(inputs);
|
||||
// 判断是否为JSON格式(LLM输出转换 由LLM生成格式)
|
||||
if (StringUtils.isNotBlank(input) && isJson(input)) {
|
||||
JSONObject inputJson = JSON.parseObject(input);
|
||||
JSONObject configJson = (JSONObject) JSON.toJSON(config);
|
||||
configJson.putAll(inputJson);
|
||||
config = configJson.toJavaObject(MailSendNodeConfig.class);
|
||||
// 使用Jackson解析和合并配置
|
||||
ObjectMapper objectMapper = new ObjectMapper();
|
||||
JsonNode inputJson = objectMapper.readTree(input);
|
||||
// 将config转换为JsonNode
|
||||
JsonNode configJson = objectMapper.valueToTree(config);
|
||||
// 合并两个JSON节点
|
||||
JsonNode mergedJson = objectMapper.readerForUpdating(configJson).readValue(inputJson);
|
||||
// 转换回config对象
|
||||
config = objectMapper.treeToValue(mergedJson, MailSendNodeConfig.class);
|
||||
}
|
||||
|
||||
// 安全获取模板(使用 defaultString 避免 null)
|
||||
@@ -217,9 +221,10 @@ public class MailSendNode extends AbstractWfNode {
|
||||
if (str == null || str.trim().isEmpty()) {
|
||||
return false;
|
||||
}
|
||||
// 使用 try-with-resources 正确处理 JSONValidator 资源关闭
|
||||
try (JSONValidator validator = JSONValidator.from(str.trim())) {
|
||||
return validator.getType() == JSONValidator.Type.Object;
|
||||
try {
|
||||
ObjectMapper objectMapper = new ObjectMapper();
|
||||
objectMapper.readTree(str.trim());
|
||||
return true;
|
||||
} catch (Exception e) {
|
||||
log.warn("JSON格式校验失败: {}", e.getMessage());
|
||||
return false;
|
||||
|
||||
@@ -1,8 +1,7 @@
|
||||
package org.ruoyi.workflow.workflow.node.switcher;
|
||||
|
||||
import com.alibaba.fastjson.JSON;
|
||||
import com.alibaba.fastjson.JSONArray;
|
||||
import com.alibaba.fastjson.JSONObject;
|
||||
import com.fasterxml.jackson.databind.JsonNode;
|
||||
import com.fasterxml.jackson.databind.ObjectMapper;
|
||||
import lombok.extern.slf4j.Slf4j;
|
||||
import org.apache.commons.lang3.ObjectUtils;
|
||||
import org.apache.commons.lang3.StringUtils;
|
||||
@@ -339,23 +338,26 @@ public class SwitcherNode extends AbstractWfNode {
|
||||
String inputConfig = workflowNode.getInputConfig();
|
||||
log.info("节点 '{}' 的输入配置: {}", nodeUuid, inputConfig);
|
||||
if (StringUtils.isNotBlank(inputConfig)){
|
||||
// 解析输入配置为JSON对象
|
||||
JSONObject configJson = JSON.parseObject(inputConfig);
|
||||
// 获取 user_inputs 数组
|
||||
JSONArray userInputs = configJson.getJSONArray("user_inputs");
|
||||
if (userInputs != null && !userInputs.isEmpty()) {
|
||||
// 在 user_inputs 中查找匹配的参数名,并获取对应值
|
||||
Optional<String> valueOpt = userInputs.stream()
|
||||
.filter(JSONObject.class::isInstance)
|
||||
.map(JSONObject.class::cast)
|
||||
.filter(obj -> paramName.equals(obj.getString("name")))
|
||||
.map(matchedObj -> getValueFromInputs(nodeUuid, "input", inputs))
|
||||
.filter(Objects::nonNull)
|
||||
.findFirst();
|
||||
// 若找到匹配值,则更新结果
|
||||
if (valueOpt.isPresent()) {
|
||||
result = valueOpt.get();
|
||||
try {
|
||||
// 使用Jackson解析输入配置
|
||||
ObjectMapper objectMapper = new ObjectMapper();
|
||||
JsonNode configJson = objectMapper.readTree(inputConfig);
|
||||
// 获取 user_inputs 数组
|
||||
JsonNode userInputs = configJson.get("user_inputs");
|
||||
if (userInputs != null && userInputs.isArray()) {
|
||||
// 在 user_inputs 中查找匹配的参数名,并获取对应值
|
||||
for (JsonNode inputNode : userInputs) {
|
||||
if (inputNode.has("name") && paramName.equals(inputNode.get("name").asText())) {
|
||||
String value = getValueFromInputs(nodeUuid, "input", inputs);
|
||||
if (value != null) {
|
||||
result = value;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
} catch (Exception e) {
|
||||
log.error("解析节点输入配置失败: {}", nodeUuid, e);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,6 +1,7 @@
|
||||
package org.ruoyi.system.utils;
|
||||
|
||||
import com.alibaba.fastjson.JSONObject;
|
||||
import com.fasterxml.jackson.databind.JsonNode;
|
||||
import com.fasterxml.jackson.databind.ObjectMapper;
|
||||
import okhttp3.*;
|
||||
import org.ruoyi.common.core.utils.StringUtils;
|
||||
|
||||
@@ -42,9 +43,11 @@ public class QwenFileUploadUtils {
|
||||
if (StringUtils.isEmpty(responseBody)){
|
||||
throw new ServerException("上传失败:响应体为空");
|
||||
}
|
||||
JSONObject jsonObject = JSONObject.parseObject(responseBody);
|
||||
// 使用Jackson解析JSON
|
||||
ObjectMapper objectMapper = new ObjectMapper();
|
||||
JsonNode jsonNode = objectMapper.readTree(responseBody);
|
||||
// 千问返回的 fileId
|
||||
return jsonObject.getString("id");
|
||||
return jsonNode.get("id").asText();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user