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

jacopoc 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 51ecf97c35 Fixed: Add validation for product image file names in 
renameImage to prevent path traversal
51ecf97c35 is described below

commit 51ecf97c3572e795ba9cf7ff71e163634351865f
Author: Jacopo Cappellato <[email protected]>
AuthorDate: Mon Jul 27 18:40:43 2026 +0200

    Fixed: Add validation for product image file names in renameImage to 
prevent path traversal
    
    (cherry picked from commit cefbdb21eabb4afd56a7aa0a9d77ebcc55738fff)
---
 .../imagemanagement/ImageManagementServices.java   | 31 ++++++++++++++++++++++
 1 file changed, 31 insertions(+)

diff --git 
a/applications/product/src/main/java/org/apache/ofbiz/product/imagemanagement/ImageManagementServices.java
 
b/applications/product/src/main/java/org/apache/ofbiz/product/imagemanagement/ImageManagementServices.java
index 2c82f3ef9a..5ca3b619d8 100644
--- 
a/applications/product/src/main/java/org/apache/ofbiz/product/imagemanagement/ImageManagementServices.java
+++ 
b/applications/product/src/main/java/org/apache/ofbiz/product/imagemanagement/ImageManagementServices.java
@@ -27,6 +27,7 @@ import java.io.FileNotFoundException;
 import java.io.IOException;
 import java.nio.ByteBuffer;
 import java.nio.file.Files;
+import java.nio.file.InvalidPathException;
 import java.nio.file.Path;
 import java.nio.file.Paths;
 import java.nio.file.StandardCopyOption;
@@ -72,6 +73,28 @@ public class ImageManagementServices {
     private static int imageCount = 0;
     private static String imagePath;
 
+    /**
+     * Ensures a user-supplied image file name is safe to use as a rename 
target: it must pass
+     * {@link org.apache.ofbiz.security.SecuredUpload#isValidFileName} (no 
path separators, no
+     * traversal sequences, no denied extensions) and must resolve, once 
normalized, directly
+     * inside the given product image directory.
+     */
+    private static boolean isValidProductImageFileName(String fileName, Path 
resolvedProductDir, Delegator delegator) {
+        if (UtilValidate.isEmpty(fileName)) {
+            return false;
+        }
+        try {
+            if 
(!org.apache.ofbiz.security.SecuredUpload.isValidFileName(fileName, delegator)) 
{
+                return false;
+            }
+            Path resolvedFilePath = 
resolvedProductDir.resolve(fileName).normalize();
+            return resolvedFilePath.getParent() != null && 
resolvedFilePath.getParent().equals(resolvedProductDir);
+        } catch (IOException | InvalidPathException e) {
+            Debug.logError(e, MODULE);
+            return false;
+        }
+    }
+
     public static Map<String, Object> 
addMultipleuploadForProduct(DispatchContext dctx,
             Map<String, ? extends Object> context) throws ImageReadException {
 
@@ -890,6 +913,14 @@ public class ImageManagementServices {
             return ServiceUtil.returnError(UtilProperties.getMessage(RES_ERROR,
                     "ProductImageViewUnableWriteFile", 
UtilMisc.toMap("fileName", resolvedProductDir.toString()), locale));
         }
+        // Guard against path traversal via drDataResourceName: it must 
resolve to a plain file name
+        // directly inside the product's own image directory, with no 
separators or traversal sequences,
+        // and a supported image extension.
+        if (!isValidProductImageFileName(filenameToUse, resolvedProductDir, 
delegator)) {
+            Debug.logError("Path traversal attempt detected in rename image, 
drDataResourceName: " + filenameToUse, MODULE);
+            return ServiceUtil.returnError(UtilProperties.getMessage(RES_ERROR,
+                    "ProductImageViewUnableWriteFile", 
UtilMisc.toMap("fileName", filenameToUse), locale));
+        }
         String imageType = 
filenameToUse.substring(filenameToUse.lastIndexOf('.'));
         String imgExtension = filenameToUse.substring(filenameToUse.length() - 
3, filenameToUse.length());
         String imageUrl = imageServerUrl + "/" + productId + "/" + 
filenameToUse;

Reply via email to