|
@@ -69,9 +69,21 @@ public final class SensitivePayloadRedactor {
|
|
|
/**
|
|
/**
|
|
|
* 截断点正好落在敏感值字符串内部时的尾部:值没有闭合引号,上面的成对规则匹配不到,
|
|
* 截断点正好落在敏感值字符串内部时的尾部:值没有闭合引号,上面的成对规则匹配不到,
|
|
|
* 这里把该键冒号后的整段尾巴(到文本末尾)全部盖上。
|
|
* 这里把该键冒号后的整段尾巴(到文本末尾)全部盖上。
|
|
|
|
|
+ *
|
|
|
|
|
+ * <p>尾部用「转义感知」的 {@code (?:[^"\\]|\\.)*} 而不是 {@code [\s\S]*}:
|
|
|
|
|
+ * 后者会跨过后文里正常的闭合引号,把已经成对替换过的后续字段(含非敏感字段)一并吞掉,
|
|
|
|
|
+ * 破坏“只对敏感键动手”。转义感知版仍能吃掉含 {@code \"} 的未闭合值前缀
|
|
|
|
|
+ * (R30 的转义引号截断用例),但不会越过一个未转义的引号 —— 那意味着该值其实已闭合。
|
|
|
*/
|
|
*/
|
|
|
private static final Pattern JSON_UNTERMINATED = Pattern.compile(
|
|
private static final Pattern JSON_UNTERMINATED = Pattern.compile(
|
|
|
- "(?i)(\"(?:" + KEY_ALTERNATION + ")\"\\s*:\\s*\")[^\"]*$");
|
|
|
|
|
|
|
+ "(?i)(\"(?:" + KEY_ALTERNATION + ")\"\\s*:\\s*\")(?:[^\"\\\\]|\\\\.)*$");
|
|
|
|
|
+
|
|
|
|
|
+ /**
|
|
|
|
|
+ * 截断后的 JSON 片段里,敏感键的值是对象/数组(整体已不可解析):
|
|
|
|
|
+ * 从该 {@code {} / {@code [} 一直遮盖到文本末尾(内层非敏感键也不得漏出)。
|
|
|
|
|
+ */
|
|
|
|
|
+ private static final Pattern JSON_CONTAINER_TAIL = Pattern.compile(
|
|
|
|
|
+ "(?i)(\"(?:" + KEY_ALTERNATION + ")\"\\s*:\\s*)[\\[{][\\s\\S]*$");
|
|
|
|
|
|
|
|
private static final ObjectMapper MAPPER = new ObjectMapper();
|
|
private static final ObjectMapper MAPPER = new ObjectMapper();
|
|
|
|
|
|
|
@@ -100,7 +112,8 @@ public final class SensitivePayloadRedactor {
|
|
|
}
|
|
}
|
|
|
String withoutQuoted = JSON_QUOTED.matcher(truncated).replaceAll("$1\"" + MASK + "\"");
|
|
String withoutQuoted = JSON_QUOTED.matcher(truncated).replaceAll("$1\"" + MASK + "\"");
|
|
|
String withoutTail = JSON_UNTERMINATED.matcher(withoutQuoted).replaceAll("$1" + MASK);
|
|
String withoutTail = JSON_UNTERMINATED.matcher(withoutQuoted).replaceAll("$1" + MASK);
|
|
|
- return clamp(KEY_VALUE.matcher(withoutTail).replaceAll("$1=" + MASK));
|
|
|
|
|
|
|
+ String withoutContainer = JSON_CONTAINER_TAIL.matcher(withoutTail).replaceAll("$1" + MASK);
|
|
|
|
|
+ return clamp(KEY_VALUE.matcher(withoutContainer).replaceAll("$1=" + MASK));
|
|
|
}
|
|
}
|
|
|
|
|
|
|
|
/** 星号比原值长时(如 {@code "S1"} → {@code "***"}),最终长度仍不得超过上限。 */
|
|
/** 星号比原值长时(如 {@code "S1"} → {@code "***"}),最终长度仍不得超过上限。 */
|