Skip to content

Security: MaskingPatternLayout uses StringBuffer instead of StringBuilder #427

@sfloess

Description

@sfloess

Description

MaskingPatternLayout.maskMessage() uses StringBuffer for regex replacement, which is synchronized and slower than StringBuilder. This is a performance issue in a logging hot path.

Location

platform-core/src/main/java/org/flossware/platform/logging/MaskingPatternLayout.java:92

StringBuffer sb = new StringBuffer();

while (matcher.find()) {
  if (matcher.groupCount() > 0) {
    // Replace first capture group with REDACTED
    String replacement = matcher.group(0).replace(matcher.group(1), REDACTED);
    matcher.appendReplacement(sb, Matcher.quoteReplacement(replacement));

Impact

Severity: LOW

  1. Performance: StringBuffer is synchronized, StringBuilder is faster
  2. Not Thread-Safe Anyway: Matcher is not thread-safe, so synchronization provides no benefit
  3. Logging Hot Path: This runs on every log message, so performance matters

However, this is a minor issue since:

  • Matcher.appendReplacement() requires StringBuffer (Java API limitation)
  • Performance impact is small unless logging extremely high volume

Note

Actually, checking the Java API - Matcher.appendReplacement() only accepts StringBuffer, not StringBuilder. This is a limitation of the JDK API.

Java 9+ added Matcher.appendReplacement(StringBuilder), but for Java 8 compatibility, StringBuffer is required.

Recommendation

  1. If targeting Java 9+, use StringBuilder variant
  2. If Java 8 support needed, keep StringBuffer
  3. Document Java version requirement
  4. Consider caching compiled Pattern objects for better performance

Example Fix (Java 9+)

StringBuilder sb = new StringBuilder();
Matcher matcher = pattern.matcher(masked);

while (matcher.find()) {
  if (matcher.groupCount() > 0) {
    String replacement = matcher.group(0).replace(matcher.group(1), REDACTED);
    matcher.appendReplacement(sb, Matcher.quoteReplacement(replacement));
  } else {
    matcher.appendReplacement(sb, REDACTED);
  }
}
matcher.appendTail(sb);
masked = sb.toString();

Labels

performance, enhancement

Metadata

Metadata

Assignees

No one assigned

    Labels

    enhancementNew feature or request

    Type

    No type
    No fields configured for issues without a type.

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions