[ 
https://issues.apache.org/jira/browse/KNOX-3039?focusedWorklogId=921989&page=com.atlassian.jira.plugin.system.issuetabpanels:worklog-tabpanel#worklog-921989
 ]

ASF GitHub Bot logged work on KNOX-3039:
----------------------------------------

                Author: ASF GitHub Bot
            Created on: 04/Jun/24 14:55
            Start Date: 04/Jun/24 14:55
    Worklog Time Spent: 10m 
      Work Description: pzampino commented on code in PR #914:
URL: https://github.com/apache/knox/pull/914#discussion_r1626161972


##########
gateway-server/src/main/java/org/apache/knox/gateway/config/impl/GatewayConfigImpl.java:
##########
@@ -176,6 +176,8 @@ public class GatewayConfigImpl extends Configuration 
implements GatewayConfig {
   public static final String CLUSTER_CONFIG_MONITOR_INTERVAL_SUFFIX = 
".interval";
   public static final String CLUSTER_CONFIG_MONITOR_ENABLED_SUFFIX = 
".enabled";
 
+  private static final String ERROR_MESSAGE_SANITIZATION_ENABLED = 
GATEWAY_CONFIG_FILE_PREFIX + ".error.sanitization.enabled";
+  private static final boolean DEFAULT_ERROR_MESSAGE_SANITIZATION_ENABLED = 
true;

Review Comment:
   The convention would dictate ERROR_MESSAGE_SANITIZATION_ENABLED_DEFAULT



##########
gateway-server/src/main/java/org/apache/knox/gateway/GatewayServlet.java:
##########
@@ -277,4 +278,34 @@ public Enumeration<String> getInitParameterNames() {
       return config.getInitParameterNames();
     }
   }
+
+  private Exception sanitizeException(Exception e) {
+    if (e == null || e.getMessage() == null) {
+      return e;
+    }
+    if (!isErrorMessageSanitizationEnabled || e.getMessage() == null) {
+      return e;
+    }
+    String sanitizedMessage = 
e.getMessage().replaceAll("\\b(?:\\d{1,3}\\.){3}\\d{1,3}\\b", "[hidden]");
+    return createNewException(e, sanitizedMessage);
+  }
+
+  private <T extends Exception> T createNewException(T e, String 
sanitizedMessage) {

Review Comment:
   I would prefer this be named something like createSanitizedException, and 
encapsulate the sanitization as part of the creation of the new object. Is 
there any scenario where the message would be sanitized and not result in a new 
corresponding Exception object?



##########
gateway-server/src/main/java/org/apache/knox/gateway/GatewayServlet.java:
##########
@@ -277,4 +278,34 @@ public Enumeration<String> getInitParameterNames() {
       return config.getInitParameterNames();
     }
   }
+
+  private Exception sanitizeException(Exception e) {
+    if (e == null || e.getMessage() == null) {
+      return e;
+    }
+    if (!isErrorMessageSanitizationEnabled || e.getMessage() == null) {
+      return e;
+    }
+    String sanitizedMessage = 
e.getMessage().replaceAll("\\b(?:\\d{1,3}\\.){3}\\d{1,3}\\b", "[hidden]");
+    return createNewException(e, sanitizedMessage);

Review Comment:
   I agree that a SanitizedException class to wrap other exceptions would be 
appropriate for this. The only reason for not doing this is if upstream 
catchers of these exceptions would ignore the SanitizedException because 
they're expecting what would be wrapped thereby.



##########
gateway-server/src/main/java/org/apache/knox/gateway/GatewayServlet.java:
##########
@@ -277,4 +278,34 @@ public Enumeration<String> getInitParameterNames() {
       return config.getInitParameterNames();
     }
   }
+
+  private Exception sanitizeException(Exception e) {
+    if (e == null || e.getMessage() == null) {
+      return e;
+    }
+    if (!isErrorMessageSanitizationEnabled || e.getMessage() == null) {
+      return e;
+    }
+    String sanitizedMessage = 
e.getMessage().replaceAll("\\b(?:\\d{1,3}\\.){3}\\d{1,3}\\b", "[hidden]");
+    return createNewException(e, sanitizedMessage);
+  }
+
+  private <T extends Exception> T createNewException(T e, String 
sanitizedMessage) {
+    try {
+      Constructor<? extends Exception> constructor = 
e.getClass().getConstructor(String.class, Throwable.class);
+      T sanitizedException = (T) constructor.newInstance(sanitizedMessage, 
e.getCause());
+      sanitizedException.setStackTrace(e.getStackTrace());
+      return sanitizedException;
+    } catch (Exception ex) {
+      Exception genericException = new Exception(sanitizedMessage, 
e.getCause());
+      genericException.setStackTrace(e.getStackTrace());
+      return (T) genericException;
+    }
+  }
+
+  private <T extends Exception> T sanitizeAndRethrow(Exception e) throws T {
+    Exception sanitizedException = sanitizeException(e);
+    LOG.failedToExecuteFilter(sanitizedException);
+    throw (T) sanitizedException;

Review Comment:
   Why does this have to throw rather than simply return the sanitized 
exception?





Issue Time Tracking
-------------------

    Worklog Id:     (was: 921989)
    Time Spent: 0.5h  (was: 20m)

> Vulnerability Disclosure: IP Address Exposure in HTTP 500 Error Message
> -----------------------------------------------------------------------
>
>                 Key: KNOX-3039
>                 URL: https://issues.apache.org/jira/browse/KNOX-3039
>             Project: Apache Knox
>          Issue Type: Bug
>          Components: Server
>            Reporter: Guillermo Kardolus
>            Priority: Major
>          Time Spent: 0.5h
>  Remaining Estimate: 0h
>
> A potential security vulnerability has been identified in Apache Knox where 
> internal IP addresses are exposed in HTTP 500 error messages. This issue can 
> occur when a user modifies the URL for one of the proxy services, leading to 
> an error page that includes the IP address of the internal service.
> *Steps to Reproduce:*
>  # Navigate to a proxy service URL, for example:
> {{<[https://example.com:8443/gateway/proxy/service?scheme=https&host=example.com&port=8051]>}}
>  # Modify the {{port}} parameter to an invalid port, such as:
> {{<[https://example.com:8443/gateway/proxy/service?scheme=https&host=example.com&port=9999]>}}
>  # Observe the resulting HTTP 500 error message which includes the internal 
> IP address.
> *Observed Behavior:* The error message reveals the internal IP address in the 
> stack trace, which can be used by an attacker for port scanning and other 
> malicious activities.
> *Example:*
> {code:java}
> HTTP ERROR 500 java.io.IOException: java.io.IOException: Service connectivity 
> error.
> MESSAGE: java.io.IOException: java.io.IOException: Service connectivity error.
> ...
> CAUSED BY: java.io.IOException: Connect to example.com:9996 
> [example.com/10.140.190.10] failed: Connection refused (Connection refused)
> ... {code}
> *Expected Behavior:* Error messages should not expose internal IP addresses. 
> Instead, they should be sanitized to prevent the disclosure of sensitive 
> information.
> *Proposed Solution:*
>  # *Sanitization Mechanism:* Implement a mechanism to sanitize error messages 
> before they are sent to the client. This can include replacing IP addresses 
> with placeholders such as {{{}[hidden]{}}}.
>  # *Configuration Options:* Provide configuration options for users to enable 
> or disable this sanitization based on their security needs. By default, users 
> should opt-in to this new sanitization functionality, with an option to 
> opt-out if necessary.
>  # *Knox-specific Error Page:* Alternatively, consider implementing a 
> Knox-specific error page that displays an error message without revealing any 
> sensitive information.



--
This message was sent by Atlassian Jira
(v8.20.10#820010)

Reply via email to