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

reta pushed a commit to branch 4.0.x-fixes
in repository https://gitbox.apache.org/repos/asf/cxf.git

commit 92f01e05872f63a0212af9b73076ab8acda38cde
Author: Dmytro Sylaiev <[email protected]>
AuthorDate: Sun Nov 24 18:38:25 2024 +0200

    CXF-9082: Allow to modify sensitive header list (#2150)
    
    * CXF-9082: Allow to modify sensitive header list
    
    * Fix any sensitive information is printed to the logs
    
    * CXF-9082: Make sensitive headers a contextual prop
    
    (cherry picked from commit 537d1ddcf883c398604346392b3af1d8404e1b09)
---
 .../org/apache/cxf/transport/http/Headers.java     | 31 ++++++++++++---------
 .../org/apache/cxf/transport/http/HeadersTest.java | 32 +++++++++++++++++++---
 2 files changed, 46 insertions(+), 17 deletions(-)

diff --git 
a/rt/transports/http/src/main/java/org/apache/cxf/transport/http/Headers.java 
b/rt/transports/http/src/main/java/org/apache/cxf/transport/http/Headers.java
index 012e9f9b49..174d590885 100644
--- 
a/rt/transports/http/src/main/java/org/apache/cxf/transport/http/Headers.java
+++ 
b/rt/transports/http/src/main/java/org/apache/cxf/transport/http/Headers.java
@@ -32,6 +32,7 @@ import java.util.List;
 import java.util.Locale;
 import java.util.Map;
 import java.util.Map.Entry;
+import java.util.Set;
 import java.util.TimeZone;
 import java.util.TreeMap;
 import java.util.logging.Level;
@@ -70,8 +71,9 @@ public class Headers {
     private static final TimeZone TIME_ZONE_GMT = TimeZone.getTimeZone("GMT");
     private static final Logger LOG = LogUtils.getL7dLogger(Headers.class);
 
-    private static final List<String> SENSITIVE_HEADERS = 
Arrays.asList("Authorization", "Proxy-Authorization");
-    private static final List<Object> SENSITIVE_HEADER_MARKER = 
Arrays.asList("***");
+    private static final String SENSITIVE_HEADERS_PROP_NAME = 
"org.apache.http.sensitive.headers";
+    private static final Set<String> DEFAULT_SENSITIVE_HEADERS = 
Set.of("Authorization", "Proxy-Authorization");
+    private static final List<Object> SENSITIVE_HEADER_MARKER = 
Collections.singletonList("***");
     private static final String ALLOW_LOGGING_SENSITIVE_HEADERS = 
"allow.logging.sensitive.headers";
 
     private final Message message;
@@ -107,11 +109,11 @@ public class Headers {
      * filtered keys), so it should be used sparingly - i.e. only when debug is
      * enabled.
      */
-    static String toString(Map<String, List<Object>> headers, boolean 
logSensitiveHeaders) {
+    static String toString(Message message, boolean logSensitiveHeaders) {
         Map<String, List<Object>> filteredHeaders = new 
TreeMap<>(String.CASE_INSENSITIVE_ORDER);
-        filteredHeaders.putAll(headers);
+        filteredHeaders.putAll(CastUtils.cast(getSetProtocolHeaders(message)));
         if (!logSensitiveHeaders) {
-            for (String filteredKey : SENSITIVE_HEADERS) {
+            for (String filteredKey : getSensitiveHeaders(message)) {
                 filteredHeaders.put(filteredKey, SENSITIVE_HEADER_MARKER);
             }
         }
@@ -306,16 +308,17 @@ public class Headers {
      *
      * @param logger     The Logger to log to.
      * @param level   The Logging Level.
-     * @param headersMap The Message protocol headers.
+     * @param message The Message.
      * @param logSensitiveHeaders whether to log sensitive headers
      */
     static void logProtocolHeaders(Logger logger, Level level,
-                                   Map<String, List<Object>> headersMap,
+                                   Message message,
                                    boolean logSensitiveHeaders) {
         if (logger.isLoggable(level)) {
+            Map<String, List<Object>> headersMap = 
CastUtils.cast(getSetProtocolHeaders(message));
             for (Map.Entry<String, List<Object>> entry : 
headersMap.entrySet()) {
                 String key = entry.getKey();
-                boolean sensitive = !logSensitiveHeaders && 
SENSITIVE_HEADERS.contains(key);
+                boolean sensitive = !logSensitiveHeaders && 
getSensitiveHeaders(message).contains(key);
                 List<Object> headerList = sensitive ? SENSITIVE_HEADER_MARKER 
: entry.getValue();
                 for (Object value : headerList) {
                     logger.log(level, key + ": "
@@ -366,8 +369,7 @@ public class Headers {
 
         transferProtocolHeadersToURLConnection(connection);
 
-        Map<String, List<Object>> theHeaders = CastUtils.cast(headers);
-        logProtocolHeaders(LOG, Level.FINE, theHeaders, logSensitiveHeaders());
+        logProtocolHeaders(LOG, Level.FINE, message, logSensitiveHeaders());
     }
 
     public String determineContentType() {
@@ -451,9 +453,7 @@ public class Headers {
             headers.put(Message.CONTENT_TYPE, 
Collections.singletonList(req.getContentType()));
         }
         if (LOG.isLoggable(Level.FINE)) {
-            Map<String, List<Object>> theHeaders = CastUtils.cast(headers);
-            LOG.log(Level.FINE, "Request Headers: " + toString(theHeaders,
-                                                               
logSensitiveHeaders()));
+            LOG.log(Level.FINE, "Request Headers: " + toString(message, 
logSensitiveHeaders()));
         }
     }
 
@@ -580,4 +580,9 @@ public class Headers {
     public static String toHttpLanguage(Locale locale) {
         return locale.toString().replace('_', '-');
     }
+
+    static Set<String> getSensitiveHeaders(Message message) {
+        return MessageUtils.getContextualStrings(message, 
SENSITIVE_HEADERS_PROP_NAME,
+                DEFAULT_SENSITIVE_HEADERS);
+    }
 }
diff --git 
a/rt/transports/http/src/test/java/org/apache/cxf/transport/http/HeadersTest.java
 
b/rt/transports/http/src/test/java/org/apache/cxf/transport/http/HeadersTest.java
index 4caadf0c28..537893c6d0 100755
--- 
a/rt/transports/http/src/test/java/org/apache/cxf/transport/http/HeadersTest.java
+++ 
b/rt/transports/http/src/test/java/org/apache/cxf/transport/http/HeadersTest.java
@@ -94,13 +94,15 @@ public class HeadersTest {
 
     @Test
     public void sensitiveHeadersTest() {
+        Message message = new MessageImpl();
         Map<String, List<Object>> headerMap = new HashMap<>();
         headerMap.put("Authorization", Arrays.asList("FAIL"));
         headerMap.put("Proxy-Authorization", Arrays.asList("FAIL"));
         headerMap.put("Content-Type", Arrays.asList("application/xml"));
         headerMap.put("Accept", Arrays.asList("text/plain"));
+        message.put(Message.PROTOCOL_HEADERS, headerMap);
 
-        String loggedString = Headers.toString(headerMap, false);
+        String loggedString = Headers.toString(message, false);
         assertFalse("The value of a sensitive header could be logged: " + 
loggedString, loggedString.contains("FAIL"));
         assertTrue("The value of a non-sensitive header would not be logged: " 
+ loggedString,
                    loggedString.contains("application/xml") && 
loggedString.contains("text/plain"));
@@ -109,6 +111,26 @@ public class HeadersTest {
                    && loggedString.contains("Accept") && 
loggedString.contains("Content-Type"));
     }
 
+    @Test
+    public void customSensitiveHeadersTest() {
+        Message message = new MessageImpl();
+        Map<String, List<Object>> headerMap = new HashMap<>();
+        headerMap.put("Authorization", Arrays.asList("FAIL"));
+        headerMap.put("MyCustomHeader", Arrays.asList("Value1"));
+        headerMap.put("NotMyCustomHeader", Arrays.asList("Value2"));
+        message.put(Message.PROTOCOL_HEADERS, headerMap);
+        message.put("org.apache.http.sensitive.headers", 
"Authorization,MyCustomHeader");
+
+        String loggedString = Headers.toString(message, false);
+
+        assertFalse("The value of a custom sensitive header should not be 
logged: "
+                + loggedString, loggedString.contains("FAIL"));
+        assertFalse("The value of a custom sensitive header should not be 
logged: "
+                + loggedString, loggedString.contains("Value1"));
+        assertTrue("The value of a not sensitive header should be logged: "
+                + loggedString, loggedString.contains("Value2"));
+    }
+
     @Test
     public void logProtocolHeadersTest() {
         Map<String, List<Object>> headerMap = new HashMap<>();
@@ -116,6 +138,8 @@ public class HeadersTest {
         headerMap.put("Multivalue-Header", Arrays.asList("first", "second"));
         headerMap.put("Authorization", Arrays.asList("myPassword"));
         headerMap.put("Null-Header", Arrays.asList((String)null));
+        Message message = new MessageImpl();
+        message.put(Message.PROTOCOL_HEADERS, headerMap);
 
         //Set up test logger
         Logger logger = Logger.getAnonymousLogger();
@@ -159,7 +183,7 @@ public class HeadersTest {
                 // no-op
             } });
 
-        Headers.logProtocolHeaders(logger, Level.INFO, headerMap, false);
+        Headers.logProtocolHeaders(logger, Level.INFO, message, false);
     }
 
     @Test
@@ -199,7 +223,7 @@ public class HeadersTest {
         assertEquals("Unexpected content-type determined - expected text/xml", 
"text/xml",
                      headers.determineContentType());
     }
-    
+
     @Test
     public void httpLanguage() {
         Locale locale = new Locale("en", "US");
@@ -214,4 +238,4 @@ public class HeadersTest {
         locale = new Locale("es", "");
         assertEquals("es", Headers.toHttpLanguage(locale));
     }
-}
\ No newline at end of file
+}

Reply via email to