Skip to content

Commit f305912

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

1 file changed

Lines changed: 10 additions & 6 deletions

File tree

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

Lines changed: 10 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -438,26 +438,30 @@ 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()) {
449-
java.util.Collection<String> names = auth.propertyNames();
450-
while (!names.isEmpty()) {
451-
((tools.jackson.databind.node.ObjectNode) auth)
452-
.put(names.iterator().next(), "<redacted>");
453+
tools.jackson.databind.node.ObjectNode sanitizedAuth =
454+
(tools.jackson.databind.node.ObjectNode) sanitized.path("params").path("auth");
455+
for (String name : auth.propertyNames()) {
456+
sanitizedAuth.put(name, "<redacted>");
453457
}
454458
}
455459
JsonNode device = root.path("params").path("device");
456460
if (device.isObject() && device.has("signature")) {
457-
((tools.jackson.databind.node.ObjectNode) device)
461+
((tools.jackson.databind.node.ObjectNode) sanitized.path("params").path("device"))
458462
.put("signature", "<redacted>");
459463
}
460-
return objectMapper.writeValueAsString(root);
464+
return objectMapper.writeValueAsString(sanitized);
461465
} catch (JacksonException e) {
462466
return "<connect-payload-redacted>";
463467
}

0 commit comments

Comments
 (0)