Skip to content

Commit e742685

Browse files
committed
fix: make connect handshake redaction thread-safe (build sanitized copy instead of mutating shared JsonNode)
1 parent 967db54 commit e742685

1 file changed

Lines changed: 9 additions & 4 deletions

File tree

src/main/java/io/github/easy4j/openclaw/ws/OpenClawGatewayWsClient.java

Lines changed: 9 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -438,26 +438,31 @@ private String requireConnectValue(String value, String name) {
438438
/**
439439
* 对 connect BODY 调试日志中的认证材料和设备签名脱敏。
440440
*
441+
* <p>基于深拷贝构造仅用于日志的脱敏副本,解析出的原始树保持只读;副本为调用线程私有,
442+
* 因此本方法天然线程安全,可在任意线程(如 WebSocket 读线程)并发调用。</p>
443+
*
441444
* @param json 原始 connect 请求 JSON
442445
* @return 保留协议结构但不包含认证秘密和设备签名的 JSON
443446
*/
444447
String redactConnectHandshake(String json) {
445448
try {
446449
JsonNode root = objectMapper.readTree(json);
450+
JsonNode sanitized = root.deepCopy();
447451
JsonNode auth = root.path("params").path("auth");
448452
if (auth.isObject()) {
453+
com.fasterxml.jackson.databind.node.ObjectNode sanitizedAuth =
454+
(com.fasterxml.jackson.databind.node.ObjectNode) sanitized.path("params").path("auth");
449455
Iterator<String> names = auth.fieldNames();
450456
while (names.hasNext()) {
451-
((com.fasterxml.jackson.databind.node.ObjectNode) auth)
452-
.put(names.next(), "<redacted>");
457+
sanitizedAuth.put(names.next(), "<redacted>");
453458
}
454459
}
455460
JsonNode device = root.path("params").path("device");
456461
if (device.isObject() && device.has("signature")) {
457-
((com.fasterxml.jackson.databind.node.ObjectNode) device)
462+
((com.fasterxml.jackson.databind.node.ObjectNode) sanitized.path("params").path("device"))
458463
.put("signature", "<redacted>");
459464
}
460-
return objectMapper.writeValueAsString(root);
465+
return objectMapper.writeValueAsString(sanitized);
461466
} catch (JsonProcessingException e) {
462467
return "<connect-payload-redacted>";
463468
}

0 commit comments

Comments
 (0)