This is an automated email from the ASF dual-hosted git repository.

ashakirin pushed a commit to branch 
feature/CXF-8099_mask_sensitive_logging_elements
in repository https://gitbox.apache.org/repos/asf/cxf.git


The following commit(s) were added to 
refs/heads/feature/CXF-8099_mask_sensitive_logging_elements by this push:
     new 6cf4ea9  CXF-8099: introduced sensitive headers
6cf4ea9 is described below

commit 6cf4ea9cc1340af99a3774e43c4064e58cc4e66b
Author: ashakirin <49843238+ashakirin-tal...@users.noreply.github.com>
AuthorDate: Mon Jul 6 02:00:17 2020 +0200

    CXF-8099: introduced sensitive headers
---
 .../ext/logging/AbstractLoggingInterceptor.java    | 12 ++++---
 .../org/apache/cxf/ext/logging/LoggingFeature.java | 31 +++++++++++++---
 .../cxf/ext/logging/MaskSensitiveHelper.java       | 42 +++++++++++++++-------
 ...itiveTest.java => MaskSensitiveHelperTest.java} | 23 ++++++++----
 4 files changed, 79 insertions(+), 29 deletions(-)

diff --git 
a/rt/features/logging/src/main/java/org/apache/cxf/ext/logging/AbstractLoggingInterceptor.java
 
b/rt/features/logging/src/main/java/org/apache/cxf/ext/logging/AbstractLoggingInterceptor.java
index 91a4adc..b4982c4 100644
--- 
a/rt/features/logging/src/main/java/org/apache/cxf/ext/logging/AbstractLoggingInterceptor.java
+++ 
b/rt/features/logging/src/main/java/org/apache/cxf/ext/logging/AbstractLoggingInterceptor.java
@@ -46,7 +46,7 @@ public abstract class AbstractLoggingInterceptor extends 
AbstractPhaseIntercepto
     protected LogEventSender sender;
     protected final DefaultLogEventMapper eventMapper = new 
DefaultLogEventMapper();
 
-    private MaskSensitiveHelper maskSensitiveHelper;
+    final MaskSensitiveHelper maskSensitiveHelper = new MaskSensitiveHelper();
 
     public AbstractLoggingInterceptor(String phase, LogEventSender sender) {
         super(phase);
@@ -78,8 +78,12 @@ public abstract class AbstractLoggingInterceptor extends 
AbstractPhaseIntercepto
         return threshold;
     }
 
-    public void setSensitiveElementNames(final List<String> 
sensitiveElementNames) {
-        maskSensitiveHelper = new MaskSensitiveHelper(sensitiveElementNames);
+    public void addSensitiveElementNames(final List<String> 
sensitiveElementNames) {
+        maskSensitiveHelper.addSensitiveElementNames(sensitiveElementNames);
+    }
+
+    public void addSensitiveHeaders(final List<String> sensitiveHeaders) {
+        maskSensitiveHelper.addSensitiveHeaders(sensitiveHeaders);
     }
 
     public void setPrettyLogging(boolean prettyLogging) {
@@ -116,7 +120,7 @@ public abstract class AbstractLoggingInterceptor extends 
AbstractPhaseIntercepto
     }
 
     protected String maskSensitiveElements(final Message message, String 
originalLogString) {
-        return Optional.ofNullable(maskSensitiveHelper)
+        return Optional.of(maskSensitiveHelper)
                 .map(h -> h.maskSensitiveElements(message, originalLogString))
                 .orElse(originalLogString);
     }
diff --git 
a/rt/features/logging/src/main/java/org/apache/cxf/ext/logging/LoggingFeature.java
 
b/rt/features/logging/src/main/java/org/apache/cxf/ext/logging/LoggingFeature.java
index afd905f..c490588 100644
--- 
a/rt/features/logging/src/main/java/org/apache/cxf/ext/logging/LoggingFeature.java
+++ 
b/rt/features/logging/src/main/java/org/apache/cxf/ext/logging/LoggingFeature.java
@@ -147,8 +147,24 @@ public class LoggingFeature extends 
DelegatingFeature<LoggingFeature.Portable> {
      * </pre>
      * @param sensitiveElementNames list of sensitive element names to be 
replaced
      */
-    public void setSensitiveElementNames(final List<String> 
sensitiveElementNames) {
-        delegate.setSensitiveElementNames(sensitiveElementNames);
+    public void addSensitiveElementNames(final List<String> 
sensitiveElementNames) {
+        delegate.addSensitiveElementNames(sensitiveElementNames);
+    }
+
+    /**
+     * Sets list of protocol headers containing sensitive information to be 
masked.
+     * Corresponded data will be replaced with configured mask
+     * For example:
+     * <pre>
+     * sensitiveHeaders: {Authorization}
+     *
+     * Initial logging statement: {Authorization=Basic 
QWxhZGRpbjpPcGVuU2VzYW1l}
+     * Result logging statement: {Authorization=XXX}
+     * </pre>
+     * @param sensitiveHeaders list of sensitive element names to be replaced
+     */
+    public void addSensitiveHeaders(final List<String> sensitiveHeaders) {
+        delegate.addSensitiveHeaders(sensitiveHeaders);
     }
 
     public static class Portable implements AbstractPortableFeature {
@@ -236,9 +252,14 @@ public class LoggingFeature extends 
DelegatingFeature<LoggingFeature.Portable> {
             addOutBinaryContentMediaTypes(mediaTypes);
         }
 
-        public void setSensitiveElementNames(final List<String> 
sensitiveElementNames) {
-            in.setSensitiveElementNames(sensitiveElementNames);
-            out.setSensitiveElementNames(sensitiveElementNames);
+        public void addSensitiveElementNames(final List<String> 
sensitiveElementNames) {
+            in.addSensitiveElementNames(sensitiveElementNames);
+            out.addSensitiveElementNames(sensitiveElementNames);
+        }
+
+        public void addSensitiveHeaders(final List<String> sensitiveHeaders) {
+            in.addSensitiveHeaders(sensitiveHeaders);
+            out.addSensitiveHeaders(sensitiveHeaders);
         }
     }
 }
diff --git 
a/rt/features/logging/src/main/java/org/apache/cxf/ext/logging/MaskSensitiveHelper.java
 
b/rt/features/logging/src/main/java/org/apache/cxf/ext/logging/MaskSensitiveHelper.java
index 4d50da6..029a561 100644
--- 
a/rt/features/logging/src/main/java/org/apache/cxf/ext/logging/MaskSensitiveHelper.java
+++ 
b/rt/features/logging/src/main/java/org/apache/cxf/ext/logging/MaskSensitiveHelper.java
@@ -18,7 +18,9 @@
  */
 package org.apache.cxf.ext.logging;
 
+import java.util.ArrayList;
 import java.util.List;
+import java.util.Optional;
 
 import org.apache.cxf.message.Message;
 
@@ -26,44 +28,58 @@ public class MaskSensitiveHelper {
     private static final String ELEMENT_NAME_TEMPLATE = "-ELEMENT_NAME-";
     private static final String MATCH_PATTERN_XML = 
"<-ELEMENT_NAME->(.*?)</-ELEMENT_NAME->";
     private static final String MATCH_PATTERN_JSON = "\"-ELEMENT_NAME-\"[ 
\\t]*:[ \\t]*\"(.*?)\"";
+    private static final String MATCH_PATTERN_HEADER = "-ELEMENT_NAME-[ 
\\t]*=([^,}])+";
     private static final String REPLACEMENT_PATTERN_XML = 
"<-ELEMENT_NAME->XXX</-ELEMENT_NAME->";
     private static final String REPLACEMENT_PATTERN_JSON = 
"\"-ELEMENT_NAME-\": \"XXX\"";
+    private static final String REPLACEMENT_PATTERN_HEADER = 
"-ELEMENT_NAME-=XXX";
 
     private static final String XML_CONTENT = "xml";
     private static final String HTML_CONTENT = "html";
     private static final String JSON_CONTENT = "json";
 
-    final List<String> sensitiveElementNames;
+    final List<String> sensitiveElementNames = new ArrayList<>();
+    final List<String> sensitiveHeaders = new ArrayList<>();
 
-    public MaskSensitiveHelper(final List<String> sensitiveElementNames) {
-        this.sensitiveElementNames = sensitiveElementNames;
+    public void addSensitiveElementNames(final List<String> 
inSensitiveElementNames) {
+        this.sensitiveElementNames.addAll(inSensitiveElementNames);
+    }
+
+    public void addSensitiveHeaders(final List<String> inSensitiveHeaders) {
+        this.sensitiveHeaders.addAll(inSensitiveHeaders);
     }
 
     public String maskSensitiveElements(
             final Message message,
             final String originalLogString) {
-        if ((sensitiveElementNames == null) || 
sensitiveElementNames.isEmpty()) {
+        if (sensitiveElementNames.isEmpty() || message == null) {
             return originalLogString;
         }
-        String contentType = (String) message.get(Message.CONTENT_TYPE);
+        final String contentType = (String) message.get(Message.CONTENT_TYPE);
         if (contentType.toLowerCase().contains(XML_CONTENT)
                 || contentType.toLowerCase().contains(HTML_CONTENT)) {
-            return applyExpression(originalLogString, MATCH_PATTERN_XML, 
REPLACEMENT_PATTERN_XML);
+            return applyMasks(originalLogString, MATCH_PATTERN_XML, 
REPLACEMENT_PATTERN_XML);
         } else if (contentType.toLowerCase().contains(JSON_CONTENT)) {
-            return applyExpression(originalLogString, MATCH_PATTERN_JSON, 
REPLACEMENT_PATTERN_JSON);
-        } else {
-            return originalLogString;
+            return applyMasks(originalLogString, MATCH_PATTERN_JSON, 
REPLACEMENT_PATTERN_JSON);
         }
+        return originalLogString;
+    }
+
+    private String applyMasks(String originalLogString, String 
matchElementPattern, String replacementElementPattern) {
+        return Optional.ofNullable(originalLogString)
+                .map(s -> applyExpression(s, MATCH_PATTERN_HEADER, 
REPLACEMENT_PATTERN_HEADER, sensitiveHeaders))
+                .map(s -> applyExpression(s, matchElementPattern, 
replacementElementPattern, sensitiveElementNames))
+                .orElse(originalLogString);
     }
 
     private String applyExpression(
             final String originalLogString,
             final String matchPatternTemplate,
-            final String replacementTemplate) {
+            final String replacementTemplate,
+            final List<String> sensitiveNames) {
         String resultString = originalLogString;
-        for (final String elementName : sensitiveElementNames) {
-            final String matchPattern = 
matchPatternTemplate.replaceAll(ELEMENT_NAME_TEMPLATE, elementName);
-            final String replacement = 
replacementTemplate.replaceAll(ELEMENT_NAME_TEMPLATE, elementName);
+        for (final String sensitiveName : sensitiveNames) {
+            final String matchPattern = 
matchPatternTemplate.replaceAll(ELEMENT_NAME_TEMPLATE, sensitiveName);
+            final String replacement = 
replacementTemplate.replaceAll(ELEMENT_NAME_TEMPLATE, sensitiveName);
             resultString = resultString.replaceAll(matchPattern, replacement);
         }
         return resultString;
diff --git 
a/rt/features/logging/src/test/java/org/apache/cxf/ext/logging/MaskSensitiveTest.java
 
b/rt/features/logging/src/test/java/org/apache/cxf/ext/logging/MaskSensitiveHelperTest.java
similarity index 84%
rename from 
rt/features/logging/src/test/java/org/apache/cxf/ext/logging/MaskSensitiveTest.java
rename to 
rt/features/logging/src/test/java/org/apache/cxf/ext/logging/MaskSensitiveHelperTest.java
index 997dcb9..8e30d5f 100644
--- 
a/rt/features/logging/src/test/java/org/apache/cxf/ext/logging/MaskSensitiveTest.java
+++ 
b/rt/features/logging/src/test/java/org/apache/cxf/ext/logging/MaskSensitiveHelperTest.java
@@ -43,7 +43,12 @@ import static org.junit.Assert.assertEquals;
 import static org.junit.Assert.assertNotNull;
 
 @RunWith(Parameterized.class)
-public class MaskSensitiveTest {
+public class MaskSensitiveHelperTest {
+
+    private static final String SENSITIVE_LOGGING_CONTENT_HEADER =
+            "{Accept=application/json, SessionId = sensitive data , 
Authorization=sensitive data}";
+    private static final String MASKED_LOGGING_CONTENT_HEADER =
+            "{Accept=application/json, SessionId=XXX, Authorization=XXX}";
 
     private static final String SENSITIVE_LOGGING_CONTENT_XML =
             "<user>testUser</user><password>my secret password</password>";
@@ -56,6 +61,7 @@ public class MaskSensitiveTest {
             "\"user\":\"testUser\", \"password\": \"XXX\"";
 
     private static final List<String> SENSITIVE_ELEMENTS = 
Arrays.asList("password");
+    private static final List<String> SENSITIVE_HEADERS = 
Arrays.asList("SessionId", "Authorization");
     private static final String APPLICATION_XML = "application/xml";
     private static final String APPLICATION_JSON = "application/json";
 
@@ -63,7 +69,7 @@ public class MaskSensitiveTest {
     private final String maskedContent;
     private final String contentType;
     private LogEventSenderMock logEventSender = new LogEventSenderMock();
-    public MaskSensitiveTest(String loggingContent, String maskedContent, 
String contentType) {
+    public MaskSensitiveHelperTest(String loggingContent, String 
maskedContent, String contentType) {
         this.loggingContent = loggingContent;
         this.maskedContent = maskedContent;
         this.contentType = contentType;
@@ -71,17 +77,19 @@ public class MaskSensitiveTest {
 
     @Parameterized.Parameters
     public static Collection primeNumbers() {
-        return Arrays.asList(new Object[][]{
+        return Arrays.asList(new Object[][] {
             {SENSITIVE_LOGGING_CONTENT_XML, MASKED_LOGGING_CONTENT_XML, 
APPLICATION_XML},
-            {SENSITIVE_LOGGING_CONTENT_JSON, MASKED_LOGGING_CONTENT_JSON, 
APPLICATION_JSON}
+            {SENSITIVE_LOGGING_CONTENT_JSON, MASKED_LOGGING_CONTENT_JSON, 
APPLICATION_JSON},
+            {SENSITIVE_LOGGING_CONTENT_HEADER, MASKED_LOGGING_CONTENT_HEADER, 
APPLICATION_JSON}
         });
     }
 
     @Test
-    public void shouldReplaceSensitiveDataIn() throws IOException {
+    public void shouldReplaceSensitiveDataIn() {
         // Arrange
         final LoggingInInterceptor inInterceptor = new 
LoggingInInterceptor(logEventSender);
-        inInterceptor.setSensitiveElementNames(SENSITIVE_ELEMENTS);
+        inInterceptor.addSensitiveElementNames(SENSITIVE_ELEMENTS);
+        inInterceptor.addSensitiveHeaders(SENSITIVE_HEADERS);
 
         final Message message = prepareInMessage();
 
@@ -102,7 +110,8 @@ public class MaskSensitiveTest {
     public void shouldReplaceSensitiveDataOut() throws IOException {
         // Arrange
         final LoggingOutInterceptor outInterceptor = new 
LoggingOutInterceptor(logEventSender);
-        outInterceptor.setSensitiveElementNames(SENSITIVE_ELEMENTS);
+        outInterceptor.addSensitiveElementNames(SENSITIVE_ELEMENTS);
+        outInterceptor.addSensitiveHeaders(SENSITIVE_HEADERS);
 
         final Message message = prepareOutMessage();
 

Reply via email to