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

jleroux pushed a commit to branch release24.09
in repository https://gitbox.apache.org/repos/asf/ofbiz-framework.git


The following commit(s) were added to refs/heads/release24.09 by this push:
     new bb743ddff1 Fixed: [SECURITY] (CVE-2024-36104) Path traversal leading 
to RCE (OFBIZ-13092)
bb743ddff1 is described below

commit bb743ddff1fddbbea94c1415159f0d4d5013d592
Author: Jacques Le Roux <jacques.le.r...@les7arts.com>
AuthorDate: Fri Jan 17 10:59:28 2025 +0100

    Fixed: [SECURITY] (CVE-2024-36104) Path traversal leading to RCE 
(OFBIZ-13092)
    
    Adds a StringUtil::splitWithStringSeparator. I crossed issue using
    StringUtil::split it's said that <<delim the delimiter character(s)>> with 
a (s)
    But it does not work as expected with several character(s).
    
    In ControlFilter::doFilter uses splitWithStringSeparator instead of split.
    Uses decoded requestUri everywhere, and to split query string, though it 
worked,
    "&amp;" rather than "Y&amp;".
    Also put all the privates methods used by doFilter just above it to clarify 
use.
    
    Conflict handled by hand in StringUtil.java
---
 .../org/apache/ofbiz/base/util/StringUtil.java     | 14 +++++
 .../apache/ofbiz/webapp/control/ControlFilter.java | 70 +++++++++++-----------
 2 files changed, 49 insertions(+), 35 deletions(-)

diff --git 
a/framework/base/src/main/java/org/apache/ofbiz/base/util/StringUtil.java 
b/framework/base/src/main/java/org/apache/ofbiz/base/util/StringUtil.java
index 8179fdcced..86f3b0c6e7 100644
--- a/framework/base/src/main/java/org/apache/ofbiz/base/util/StringUtil.java
+++ b/framework/base/src/main/java/org/apache/ofbiz/base/util/StringUtil.java
@@ -136,6 +136,20 @@ public final class StringUtil {
         return splitList;
     }
 
+    /**
+     * Splits a String on a String Separator into a List of Strings.
+     * @param str the String to split
+     * @param separator the String Separator to split the str String
+     * @return a list of Strings or null if one of the parameters is null
+     */
+    public static List<String> splitWithStringSeparator(String str, String 
separator) {
+        if (str == null || separator == null) {
+            return null;
+        }
+
+        return Arrays.asList(str.split(separator));
+    }
+
     /**
      * Creates a Map from an encoded name/value pair string
      * @param str The string to decode and format
diff --git 
a/framework/webapp/src/main/java/org/apache/ofbiz/webapp/control/ControlFilter.java
 
b/framework/webapp/src/main/java/org/apache/ofbiz/webapp/control/ControlFilter.java
index 8ed0cd9df1..2fb2439501 100644
--- 
a/framework/webapp/src/main/java/org/apache/ofbiz/webapp/control/ControlFilter.java
+++ 
b/framework/webapp/src/main/java/org/apache/ofbiz/webapp/control/ControlFilter.java
@@ -140,8 +140,41 @@ public class ControlFilter extends HttpFilter {
         return 
!GenericValue.getStackTraceAsString().contains("ControlFilterTests")
                 && null == System.getProperty("SolrDispatchFilter");
     }
+
+    /**
+     * Sends an HTTP response redirecting to {@code redirectPath}.
+     * @param resp The response to send
+     * @param contextPath the prefix to add to the redirection when
+     * {@code redirectPath} is a relative URI.
+     * @throws IOException when redirection has not been properly sent.
+     */
+    private void redirect(HttpServletResponse resp, String contextPath) throws 
IOException {
+        resp.sendRedirect(redirectPathIsUrl ? redirectPath : (contextPath + 
redirectPath));
+    }
+
+    private static List<String> getAllowedTokens() {
+        String allowedTokens = UtilProperties.getPropertyValue("security", 
"allowedTokens");
+        return UtilValidate.isNotEmpty(allowedTokens) ? 
StringUtil.split(allowedTokens, ",") : new ArrayList<>();
+    }
+
+    // Check there is any allowedToken in URL
+    private static boolean isAnyAllowedToken(List<String> queryParameters, 
List<String> allowed) {
+        boolean isOK = false;
+        for (String parameter : queryParameters) {
+            parameter = parameter.substring(0, parameter.indexOf("=") + 1);
+            if (allowed.contains(HashCrypt.cryptBytes("SHA", "OFBiz", 
parameter.getBytes(StandardCharsets.UTF_8)))) {
+                isOK = true;
+                break;
+            } else {
+                continue;
+            }
+        }
+        return isOK;
+    }
+
     /**
      * Makes allowed paths pass through while redirecting the others to a fix 
location.
+     * Reject wrong URLs
      */
     @Override
     public void doFilter(HttpServletRequest req, HttpServletResponse resp, 
FilterChain chain) throws IOException, ServletException {
@@ -193,7 +226,8 @@ public class ControlFilter extends HttpFilter {
             }
             boolean bypass = true;
             if (queryString != null) {
-                bypass = 
isAnyAllowedToken(StringUtil.split(queryString.toLowerCase(), "Y&amp;"), 
ALLOWEDTOKENS);
+                List<String> queryStringList = 
StringUtil.splitWithStringSeparator(queryString.toLowerCase(), "&amp;");
+                bypass = isAnyAllowedToken(queryStringList, ALLOWEDTOKENS);
             }
             if (uriWithContext != null && !bypass) { // "null" allows tests 
with Mockito. ControlFilterTests sends null.
                 try {
@@ -233,38 +267,4 @@ public class ControlFilter extends HttpFilter {
             }
         }
     }
-
-    /**
-     * Sends an HTTP response redirecting to {@code redirectPath}.
-     * @param resp The response to send
-     * @param contextPath the prefix to add to the redirection when
-     * {@code redirectPath} is a relative URI.
-     * @throws IOException when redirection has not been properly sent.
-     */
-    private void redirect(HttpServletResponse resp, String contextPath) throws 
IOException {
-        resp.sendRedirect(redirectPathIsUrl ? redirectPath : (contextPath + 
redirectPath));
-    }
-
-    private static List<String> getAllowedTokens() {
-        String allowedTokens = UtilProperties.getPropertyValue("security", 
"allowedTokens");
-        return UtilValidate.isNotEmpty(allowedTokens) ? 
StringUtil.split(allowedTokens, ",") : new ArrayList<>();
-    }
-
-
-
-
-    // Check there is any allowedToken in URL
-    private static boolean isAnyAllowedToken(List<String> queryParameters, 
List<String> allowed) {
-        boolean isOK = false;
-        for (String parameter : queryParameters) {
-            parameter = parameter.substring(0, parameter.indexOf("=") + 1);
-            if (allowed.contains(HashCrypt.cryptBytes("SHA", "OFBiz", 
parameter.getBytes(StandardCharsets.UTF_8)))) {
-                isOK = true;
-                break;
-            } else {
-                continue;
-            }
-        }
-        return isOK;
-    }
 }

Reply via email to