diff --git a/server/sonar-process/src/main/java/org/sonar/process/logging/DataMaskingPatternClassicLayout.java b/server/sonar-process/src/main/java/org/sonar/process/logging/DataMaskingPatternClassicLayout.java new file mode 100644 index 000000000000..ae15b77fc9a2 --- /dev/null +++ b/server/sonar-process/src/main/java/org/sonar/process/logging/DataMaskingPatternClassicLayout.java @@ -0,0 +1,33 @@ +/* + * SonarQube + * Copyright (C) 2009-2023 SonarSource SA + * mailto:info AT sonarsource DOT com + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 3 of the License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public License + * along with this program; if not, write to the Free Software Foundation, + * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + */ +package org.sonar.process.logging; + +import static org.sonar.process.logging.LogMaskingUtil.maskEmail; + +import ch.qos.logback.classic.PatternLayout; +import ch.qos.logback.classic.spi.ILoggingEvent; + +public class DataMaskingPatternClassicLayout extends PatternLayout { + + @Override + public String doLayout(ILoggingEvent event) { + return maskEmail(super.doLayout(event)); + } +} \ No newline at end of file diff --git a/server/sonar-process/src/main/java/org/sonar/process/logging/LogMaskingUtil.java b/server/sonar-process/src/main/java/org/sonar/process/logging/LogMaskingUtil.java new file mode 100644 index 000000000000..bae2ef74e213 --- /dev/null +++ b/server/sonar-process/src/main/java/org/sonar/process/logging/LogMaskingUtil.java @@ -0,0 +1,53 @@ +/* + * SonarQube + * Copyright (C) 2009-2023 SonarSource SA + * mailto:info AT sonarsource DOT com + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 3 of the License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public License + * along with this program; if not, write to the Free Software Foundation, + * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + */ +package org.sonar.process.logging; + +import java.util.regex.Matcher; +import java.util.regex.Pattern; +import java.util.stream.IntStream; +import org.apache.commons.lang.StringUtils; + + +public class LogMaskingUtil { + + public static final Pattern MASK_EMAIL_PATTERN = Pattern.compile("([\\w.\\-+_]+)@[\\w.\\-+_]+\\.\\w+", + Pattern.MULTILINE); + + public static String maskMessage(String message, Pattern pattern) { + if (StringUtils.isNotEmpty(message)) { + StringBuilder sb = new StringBuilder(message); + Matcher matcher = pattern.matcher(sb); + while (matcher.find()) { + IntStream.rangeClosed(1, matcher.groupCount()).forEach(group -> { + if (matcher.group(group) != null) { + IntStream.range(matcher.start(group), + matcher.end(group)).forEach(i -> sb.setCharAt(i, '*')); + } + }); + } + return sb.toString(); + } + return message; + } + + public static String maskEmail(String message) { + return maskMessage(message, MASK_EMAIL_PATTERN); + } +} \ No newline at end of file diff --git a/server/sonar-process/src/main/java/org/sonar/process/logging/LogbackJsonLayout.java b/server/sonar-process/src/main/java/org/sonar/process/logging/LogbackJsonLayout.java index 56904ffb05e8..52290ffe6d3f 100644 --- a/server/sonar-process/src/main/java/org/sonar/process/logging/LogbackJsonLayout.java +++ b/server/sonar-process/src/main/java/org/sonar/process/logging/LogbackJsonLayout.java @@ -19,6 +19,10 @@ */ package org.sonar.process.logging; +import static java.lang.String.format; +import static java.util.Objects.requireNonNull; +import static org.sonar.process.logging.LogMaskingUtil.maskEmail; + import ch.qos.logback.classic.spi.ILoggingEvent; import ch.qos.logback.classic.spi.IThrowableProxy; import ch.qos.logback.classic.spi.StackTraceElementProxy; @@ -35,9 +39,6 @@ import java.util.regex.Pattern; import org.apache.commons.lang.StringUtils; -import static java.lang.String.format; -import static java.util.Objects.requireNonNull; - /** * Formats logs in JSON. *
@@ -76,11 +77,14 @@ public String doLayout(ILoggingEvent event) {
json.name(entry.getKey()).value(entry.getValue());
}
}
+
+ String formattedMsg = NEWLINE_REGEXP.matcher(event.getFormattedMessage()).replaceAll("\r");
+
json
.name("timestamp").value(DATE_FORMATTER.format(Instant.ofEpochMilli(event.getTimeStamp())))
.name("severity").value(event.getLevel().toString())
.name("logger").value(event.getLoggerName())
- .name("message").value(NEWLINE_REGEXP.matcher(event.getFormattedMessage()).replaceAll("\r"));
+ .name("message").value(maskEmail(formattedMsg));
IThrowableProxy tp = event.getThrowableProxy();
if (tp != null) {
json.name("stacktrace").beginArray();
diff --git a/server/sonar-process/src/main/java/org/sonar/process/logging/PatternLayoutEncoder.java b/server/sonar-process/src/main/java/org/sonar/process/logging/PatternLayoutEncoder.java
index 8540951cae32..a69c085228c2 100644
--- a/server/sonar-process/src/main/java/org/sonar/process/logging/PatternLayoutEncoder.java
+++ b/server/sonar-process/src/main/java/org/sonar/process/logging/PatternLayoutEncoder.java
@@ -29,7 +29,7 @@ public class PatternLayoutEncoder extends PatternLayoutEncoderBase