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

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


The following commit(s) were added to refs/heads/release17.12 by this push:
     new 0a49e0a  Fixed: CVE-2021-37608 vulnerability bypass (OFBIZ-12307)
0a49e0a is described below

commit 0a49e0adddd3577f344781ddec664027d8de799d
Author: Jacques Le Roux <jacques.le.r...@les7arts.com>
AuthorDate: Fri Sep 17 11:29:43 2021 +0200

    Fixed: CVE-2021-37608 vulnerability bypass (OFBIZ-12307)
    
    Fixes a number of issues I spotted while working on OFBIZ-12305 in relation 
with
    OFBIZ-12055
    
    The last change I made for OFBIZ-12305 was incomplete, the files could not 
be
    checked by SecuredUpload because they did not exist! This concerns
    ImageManagementServices, DataServices, FrameImage and ProductServices 
classes.
    I used Files::createTempFile to fix that.
    
    Also fixes a bug in SecuredUpload where I reversed the check on
    fileToCheck.length in Windows case. I also added a comment, Windows 10 now
    allows more length (need an OS parameter change though)
    
    Finally, creates public SecuredUpload::isValidText to be used in OFBIZ-12305
    
    Conflicts handled by hand
      DataServices.java
---
 .../apache/ofbiz/content/data/DataServices.java    | 192 +++++++++++----------
 .../ofbiz/product/imagemanagement/FrameImage.java  |   8 +-
 .../imagemanagement/ImageManagementServices.java   |  21 ++-
 .../ofbiz/product/product/ProductServices.java     |   8 +-
 .../org/apache/ofbiz/security/SecuredUpload.java   |   6 +-
 5 files changed, 140 insertions(+), 95 deletions(-)

diff --git 
a/applications/content/src/main/java/org/apache/ofbiz/content/data/DataServices.java
 
b/applications/content/src/main/java/org/apache/ofbiz/content/data/DataServices.java
index b6b17df..47e5a01 100644
--- 
a/applications/content/src/main/java/org/apache/ofbiz/content/data/DataServices.java
+++ 
b/applications/content/src/main/java/org/apache/ofbiz/content/data/DataServices.java
@@ -27,6 +27,10 @@ import java.io.RandomAccessFile;
 import java.io.StringWriter;
 import java.io.Writer;
 import java.nio.ByteBuffer;
+import java.nio.charset.StandardCharsets;
+import java.nio.file.Files;
+import java.nio.file.Path;
+import java.nio.file.StandardOpenOption;
 import java.sql.Timestamp;
 import java.util.Arrays;
 import java.util.HashMap;
@@ -38,7 +42,6 @@ import org.apache.ofbiz.base.util.Debug;
 import org.apache.ofbiz.base.util.GeneralException;
 import org.apache.ofbiz.base.util.UtilDateTime;
 import org.apache.ofbiz.base.util.UtilGenerics;
-import org.apache.ofbiz.base.util.UtilIO;
 import org.apache.ofbiz.base.util.UtilMisc;
 import org.apache.ofbiz.base.util.UtilProperties;
 import org.apache.ofbiz.base.util.UtilValidate;
@@ -57,8 +60,8 @@ import org.apache.ofbiz.service.ServiceUtil;
  */
 public class DataServices {
 
-    public static final String module = DataServices.class.getName();
-    public static final String resource = "ContentUiLabels";
+    private static final String MODULE = DataServices.class.getName();
+    private static final String RESOURCE = "ContentUiLabels";
 
     public static Map<String, Object> 
clearAssociatedRenderCache(DispatchContext dctx, Map<String, Object> context) {
         Delegator delegator = dctx.getDelegator();
@@ -67,8 +70,9 @@ public class DataServices {
         try {
             DataResourceWorker.clearAssociatedRenderCache(delegator, 
dataResourceId);
         } catch (GeneralException e) {
-            Debug.logError(e, "Unable to clear associated render cache with 
dataResourceId=" + dataResourceId, module);
-            return ServiceUtil.returnError(UtilProperties.getMessage(resource, 
"ContentClearAssociatedRenderCacheError", UtilMisc.toMap("dataResourceId", 
dataResourceId), locale));
+            Debug.logError(e, "Unable to clear associated render cache with 
dataResourceId=" + dataResourceId, MODULE);
+            return ServiceUtil.returnError(UtilProperties.getMessage(RESOURCE, 
"ContentClearAssociatedRenderCacheError",
+                    UtilMisc.toMap("dataResourceId", dataResourceId), locale));
         }
         return ServiceUtil.returnSuccess();
     }
@@ -129,7 +133,7 @@ public class DataServices {
             dataResourceId = delegator.getNextSeqId("DataResource");
         }
         if (Debug.infoOn()) {
-            Debug.logInfo("in createDataResourceMethod, dataResourceId:" + 
dataResourceId, module);
+            Debug.logInfo("in createDataResourceMethod, dataResourceId:" + 
dataResourceId, MODULE);
         }
         GenericValue dataResource = delegator.makeValue("DataResource", 
UtilMisc.toMap("dataResourceId", dataResourceId));
         dataResource.setNonPKFields(context);
@@ -140,9 +144,10 @@ public class DataServices {
         // get first statusId  for content out of the statusItem table if not 
provided
         if (UtilValidate.isEmpty(dataResource.get("statusId"))) {
             try {
-                GenericValue statusItem = 
EntityQuery.use(delegator).from("StatusItem").where("statusTypeId", 
"CONTENT_STATUS").orderBy("sequenceId").queryFirst();
+                GenericValue statusItem = 
EntityQuery.use(delegator).from("StatusItem").where("statusTypeId", 
"CONTENT_STATUS")
+                        .orderBy("sequenceId").queryFirst();
                 if (statusItem != null) {
-                    dataResource.put("statusId",  statusItem.get("statusId"));
+                    dataResource.put("statusId", statusItem.get("statusId"));
                 }
             } catch (GenericEntityException e) {
                 return ServiceUtil.returnError(e.getMessage());
@@ -173,7 +178,8 @@ public class DataServices {
         String dataResourceId = (String) context.get("dataResourceId");
         String textData = (String) context.get("textData");
         if (UtilValidate.isNotEmpty(textData)) {
-            GenericValue electronicText = 
delegator.makeValue("ElectronicText", UtilMisc.toMap("dataResourceId", 
dataResourceId, "textData", textData));
+            GenericValue electronicText = delegator.makeValue("ElectronicText",
+                    UtilMisc.toMap("dataResourceId", dataResourceId, 
"textData", textData));
             try {
                 electronicText.create();
             } catch (GenericEntityException e) {
@@ -210,18 +216,19 @@ public class DataServices {
 
         // extended validation for binary/character data
         if (UtilValidate.isNotEmpty(textData) && binData != null) {
-            return ServiceUtil.returnError(UtilProperties.getMessage(resource, 
"ContentCannotProcessBothCharacterAndBinaryFile", locale));
+            return ServiceUtil.returnError(UtilProperties.getMessage(RESOURCE, 
"ContentCannotProcessBothCharacterAndBinaryFile", locale));
         }
 
         // obtain a reference to the file
         File file = null;
         if (UtilValidate.isEmpty(objectInfo)) {
-            return ServiceUtil.returnError(UtilProperties.getMessage(resource, 
"ContentUnableObtainReferenceToFile", UtilMisc.toMap("objectInfo", ""), 
locale));
+            return ServiceUtil.returnError(UtilProperties.getMessage(RESOURCE, 
"ContentUnableObtainReferenceToFile",
+                    UtilMisc.toMap("objectInfo", ""), locale));
         }
         if (UtilValidate.isEmpty(dataResourceTypeId) || 
"LOCAL_FILE".equals(dataResourceTypeId) || 
"LOCAL_FILE_BIN".equals(dataResourceTypeId)) {
             file = new File(objectInfo);
             if (!file.isAbsolute()) {
-                return 
ServiceUtil.returnError(UtilProperties.getMessage(resource, 
"ContentLocalFileDoesNotPointToAbsoluteLocation", locale));
+                return 
ServiceUtil.returnError(UtilProperties.getMessage(RESOURCE, 
"ContentLocalFileDoesNotPointToAbsoluteLocation", locale));
             }
         } else if ("OFBIZ_FILE".equals(dataResourceTypeId) || 
"OFBIZ_FILE_BIN".equals(dataResourceTypeId)) {
             prefix = System.getProperty("ofbiz.home");
@@ -232,7 +239,7 @@ public class DataServices {
         } else if ("CONTEXT_FILE".equals(dataResourceTypeId) || 
"CONTEXT_FILE_BIN".equals(dataResourceTypeId)) {
             prefix = (String) context.get("rootDir");
             if (UtilValidate.isEmpty(prefix)) {
-                return 
ServiceUtil.returnError(UtilProperties.getMessage(resource, 
"ContentCannotFindContextFileWithEmptyContextRoot", locale));
+                return 
ServiceUtil.returnError(UtilProperties.getMessage(RESOURCE, 
"ContentCannotFindContextFileWithEmptyContextRoot", locale));
             }
             if (objectInfo.indexOf('/') != 0 && prefix.lastIndexOf('/') != 
(prefix.length() - 1)) {
                 sep = "/";
@@ -240,43 +247,49 @@ public class DataServices {
             file = new File(prefix + sep + objectInfo);
         }
         if (file == null) {
-            return ServiceUtil.returnError(UtilProperties.getMessage(resource, 
"ContentUnableObtainReferenceToFile", UtilMisc.toMap("objectInfo", objectInfo), 
locale));
+            return ServiceUtil.returnError(UtilProperties.getMessage(RESOURCE, 
"ContentUnableObtainReferenceToFile",
+                    UtilMisc.toMap("objectInfo", objectInfo), locale));
         }
 
         // write the data to the file
         if (UtilValidate.isNotEmpty(textData)) {
-            try (
-                OutputStreamWriter out = new OutputStreamWriter(new 
FileOutputStream(file), UtilIO.getUtf8());
-            ) {
+            try (OutputStreamWriter out = new OutputStreamWriter(new 
FileOutputStream(file), StandardCharsets.UTF_8);) {
                 out.write(textData);
                 if 
(!org.apache.ofbiz.security.SecuredUpload.isValidFile(file.getAbsolutePath(), 
"Text", delegator)) {
                     String errorMessage = 
UtilProperties.getMessage("SecurityUiLabels", "SupportedTextFileFormats", 
locale);
                     return ServiceUtil.returnError(errorMessage);
                 }
             } catch (IOException | ImageReadException e) {
-                Debug.logWarning(e, module);
-                return 
ServiceUtil.returnError(UtilProperties.getMessage(resource, 
"ContentUnableWriteCharacterDataToFile", UtilMisc.toMap("fileName", 
file.getAbsolutePath()), locale));
+                Debug.logWarning(e, MODULE);
+                return 
ServiceUtil.returnError(UtilProperties.getMessage(RESOURCE, 
"ContentUnableWriteCharacterDataToFile",
+                        UtilMisc.toMap("fileName", file.getAbsolutePath()), 
locale));
             }
         } else if (binData != null) {
             try {
                 // Check if a webshell is not uploaded
-                if 
(!org.apache.ofbiz.security.SecuredUpload.isValidFile(file.getAbsolutePath(), 
"All", delegator)) {
+                Path tempFile = Files.createTempFile(null, null);
+                Files.write(tempFile, binData.array(), 
StandardOpenOption.APPEND);
+                if 
(!org.apache.ofbiz.security.SecuredUpload.isValidFile(tempFile.toString(), 
"All", delegator)) {
                     String errorMessage = 
UtilProperties.getMessage("SecurityUiLabels", 
"SupportedFileFormatsIncludingSvg", locale);
                     return ServiceUtil.returnError(errorMessage);
                 }
+                Files.delete(tempFile);
                 RandomAccessFile out = new RandomAccessFile(file, "rw");
                 out.write(binData.array());
                 out.close();
 
             } catch (FileNotFoundException | ImageReadException e) {
-                Debug.logError(e, module);
-                return 
ServiceUtil.returnError(UtilProperties.getMessage(resource, 
"ContentUnableToOpenFileForWriting", UtilMisc.toMap("fileName", 
file.getAbsolutePath()), locale));
+                Debug.logError(e, MODULE);
+                return 
ServiceUtil.returnError(UtilProperties.getMessage(RESOURCE, 
"ContentUnableToOpenFileForWriting",
+                        UtilMisc.toMap("fileName", file.getAbsolutePath()), 
locale));
             } catch (IOException e) {
-                Debug.logError(e, module);
-                return 
ServiceUtil.returnError(UtilProperties.getMessage(resource, 
"ContentUnableWriteBinaryDataToFile", UtilMisc.toMap("fileName", 
file.getAbsolutePath()), locale));
+                Debug.logError(e, MODULE);
+                return 
ServiceUtil.returnError(UtilProperties.getMessage(RESOURCE, 
"ContentUnableWriteBinaryDataToFile",
+                        UtilMisc.toMap("fileName", file.getAbsolutePath()), 
locale));
             }
         } else {
-            return ServiceUtil.returnError(UtilProperties.getMessage(resource, 
"ContentNoContentFilePassed", UtilMisc.toMap("fileName", 
file.getAbsolutePath()), locale));
+            return ServiceUtil.returnError(UtilProperties.getMessage(RESOURCE, 
"ContentNoContentFilePassed",
+                    UtilMisc.toMap("fileName", file.getAbsolutePath()), 
locale));
         }
 
         Map<String, Object> result = ServiceUtil.returnSuccess();
@@ -324,8 +337,9 @@ public class DataServices {
         try {
             dataResource = 
EntityQuery.use(delegator).from("DataResource").where("dataResourceId", 
dataResourceId).queryOne();
         } catch (GenericEntityException e) {
-            Debug.logWarning(e, module);
-            return ServiceUtil.returnError(UtilProperties.getMessage(resource, 
"ContentDataResourceNotFound", UtilMisc.toMap("parameters.dataResourceId", 
dataResourceId), locale));
+            Debug.logWarning(e, MODULE);
+            return ServiceUtil.returnError(UtilProperties.getMessage(RESOURCE, 
"ContentDataResourceNotFound",
+                    UtilMisc.toMap("parameters.dataResourceId", 
dataResourceId), locale));
         }
 
         dataResource.setNonPKFields(context);
@@ -335,7 +349,7 @@ public class DataServices {
         try {
             dataResource.store();
         } catch (GenericEntityException e) {
-            Debug.logError(e, module);
+            Debug.logError(e, MODULE);
             return ServiceUtil.returnError(e.getMessage());
         }
 
@@ -352,8 +366,8 @@ public class DataServices {
     }
 
     /**
-     * Because sometimes a DataResource will exist, but no ElectronicText has 
been created,
-     * this method will create an ElectronicText if it does not exist.
+     * Because sometimes a DataResource will exist, but no ElectronicText has 
been created, this method will create an
+     * ElectronicText if it does not exist.
      * @param dctx the dispatch context
      * @param context the context
      * @return update the ElectronicText
@@ -368,12 +382,12 @@ public class DataServices {
         String contentId = (String) context.get("contentId");
         result.put("contentId", contentId);
         if (UtilValidate.isEmpty(dataResourceId)) {
-            Debug.logError("dataResourceId is null.", module);
-            return ServiceUtil.returnError(UtilProperties.getMessage(resource, 
"ContentDataResourceIsNull", locale));
+            Debug.logError("dataResourceId is null.", MODULE);
+            return ServiceUtil.returnError(UtilProperties.getMessage(RESOURCE, 
"ContentDataResourceIsNull", locale));
         }
         String textData = (String) context.get("textData");
         if (Debug.verboseOn()) {
-            Debug.logVerbose("in updateElectronicText, textData:" + textData, 
module);
+            Debug.logVerbose("in updateElectronicText, textData:" + textData, 
MODULE);
         }
         try {
             electronicText = 
EntityQuery.use(delegator).from("ElectronicText").where("dataResourceId", 
dataResourceId).queryOne();
@@ -387,8 +401,8 @@ public class DataServices {
                 electronicText.create();
             }
         } catch (GenericEntityException e) {
-            Debug.logWarning(e, module);
-            return ServiceUtil.returnError(UtilProperties.getMessage(resource, 
"ContentElectronicTextNotFound", locale) + " " + e.getMessage());
+            Debug.logWarning(e, MODULE);
+            return ServiceUtil.returnError(UtilProperties.getMessage(RESOURCE, 
"ContentElectronicTextNotFound", locale) + " " + e.getMessage());
         }
 
         return result;
@@ -445,53 +459,59 @@ public class DataServices {
 
             // write the data to the file
             if (UtilValidate.isNotEmpty(textData)) {
-                try (
-                        OutputStreamWriter out = new OutputStreamWriter(new 
FileOutputStream(file),UtilIO.getUtf8());
-                ) {
+                try (OutputStreamWriter out = new OutputStreamWriter(new 
FileOutputStream(file), StandardCharsets.UTF_8);) {
                     out.write(textData);
                     if 
(!org.apache.ofbiz.security.SecuredUpload.isValidFile(file.getAbsolutePath(), 
"Text", delegator)) {
                         String errorMessage = 
UtilProperties.getMessage("SecurityUiLabels", "SupportedTextFileFormats", 
locale);
                         return ServiceUtil.returnError(errorMessage);
                     }
                 } catch (IOException | ImageReadException e) {
-                    Debug.logWarning(e, module);
-                    return 
ServiceUtil.returnError(UtilProperties.getMessage(resource, 
"ContentUnableWriteCharacterDataToFile", UtilMisc.toMap("fileName", 
file.getAbsolutePath()), locale));
+                    Debug.logWarning(e, MODULE);
+                    return 
ServiceUtil.returnError(UtilProperties.getMessage(RESOURCE, 
"ContentUnableWriteCharacterDataToFile",
+                            UtilMisc.toMap("fileName", 
file.getAbsolutePath()), locale));
                 }
             } else if (binData != null) {
                 try {
                     // Check if a webshell is not uploaded
-                    if 
(!org.apache.ofbiz.security.SecuredUpload.isValidFile(file.getAbsolutePath(), 
"All", delegator)) {
+                    Path tempFile = Files.createTempFile(null, null);
+                    Files.write(tempFile, binData.array(), 
StandardOpenOption.APPEND);
+                    if 
(!org.apache.ofbiz.security.SecuredUpload.isValidFile(tempFile.toString(), 
"Image", delegator)) {
                         String errorMessage = 
UtilProperties.getMessage("SecurityUiLabels", 
"SupportedFileFormatsIncludingSvg", locale);
                         return ServiceUtil.returnError(errorMessage);
                     }
+                    Files.delete(tempFile);
                     RandomAccessFile out = new RandomAccessFile(file, "rw");
                     out.setLength(binData.array().length);
                     out.write(binData.array());
                     out.close();
                 } catch (FileNotFoundException | ImageReadException e) {
-                    Debug.logError(e, module);
-                    return 
ServiceUtil.returnError(UtilProperties.getMessage(resource, 
"ContentUnableToOpenFileForWriting", UtilMisc.toMap("fileName", 
file.getAbsolutePath()), locale));
+                    Debug.logError(e, MODULE);
+                    return 
ServiceUtil.returnError(UtilProperties.getMessage(RESOURCE, 
"ContentUnableToOpenFileForWriting",
+                            UtilMisc.toMap("fileName", 
file.getAbsolutePath()), locale));
                 } catch (IOException e) {
-                    Debug.logError(e, module);
-                    return 
ServiceUtil.returnError(UtilProperties.getMessage(resource, 
"ContentUnableWriteBinaryDataToFile", UtilMisc.toMap("fileName", 
file.getAbsolutePath()), locale));
+                    Debug.logError(e, MODULE);
+                    return 
ServiceUtil.returnError(UtilProperties.getMessage(RESOURCE, 
"ContentUnableWriteBinaryDataToFile",
+                            UtilMisc.toMap("fileName", 
file.getAbsolutePath()), locale));
                 }
             } else {
-                return 
ServiceUtil.returnError(UtilProperties.getMessage(resource, 
"ContentNoContentFilePassed", UtilMisc.toMap("fileName", 
file.getAbsolutePath()), locale));
+                return 
ServiceUtil.returnError(UtilProperties.getMessage(RESOURCE, 
"ContentNoContentFilePassed",
+                        UtilMisc.toMap("fileName", file.getAbsolutePath()), 
locale));
             }
 
         } catch (IOException e) {
-            Debug.logWarning(e, module);
+            Debug.logWarning(e, MODULE);
             throw new GenericServiceException(e.getMessage());
         }
 
         return result;
     }
 
-    public static Map<String, Object> renderDataResourceAsText(DispatchContext 
dctx, Map<String, ? extends Object> context) throws GeneralException, 
IOException {
+    public static Map<String, Object> renderDataResourceAsText(DispatchContext 
dctx, Map<String, ? extends Object> context)
+            throws GeneralException, IOException {
         Map<String, Object> results = new HashMap<>();
         //LocalDispatcher dispatcher = dctx.getDispatcher();
         Writer out = (Writer) context.get("outWriter");
-        Map<String, Object> templateContext = 
UtilGenerics.checkMap(context.get("templateContext"));
+        Map<String, Object> templateContext = 
UtilGenerics.cast(context.get("templateContext"));
         //GenericValue userLogin = (GenericValue) context.get("userLogin");
         String dataResourceId = (String) context.get("dataResourceId");
         if (templateContext != null && UtilValidate.isEmpty(dataResourceId)) {
@@ -514,7 +534,7 @@ public class DataServices {
             out.write(outWriter.toString());
             results.put("textData", outWriter.toString());
         } catch (IOException e) {
-            Debug.logError(e, "Error rendering sub-content text", module);
+            Debug.logError(e, "Error rendering sub-content text", MODULE);
             return ServiceUtil.returnError(e.toString());
         }
         return results;
@@ -533,14 +553,15 @@ public class DataServices {
         Delegator delegator = dctx.getDelegator();
         //Locale locale = (Locale) context.get("locale");
         String dataResourceId = (String) context.get("dataResourceId");
-        ByteBuffer byteBuffer = (ByteBuffer)context.get("imageData");
+        ByteBuffer byteBuffer = (ByteBuffer) context.get("imageData");
         if (byteBuffer != null) {
             byte[] imageBytes = byteBuffer.array();
             try {
-                GenericValue imageDataResource = 
EntityQuery.use(delegator).from("ImageDataResource").where("dataResourceId", 
dataResourceId).queryOne();
+                GenericValue imageDataResource = 
EntityQuery.use(delegator).from("ImageDataResource")
+                        .where("dataResourceId", dataResourceId).queryOne();
                 if (Debug.infoOn()) {
-                    Debug.logInfo("imageDataResource(U):" + imageDataResource, 
module);
-                    Debug.logInfo("imageBytes(U):" + 
Arrays.toString(imageBytes), module);
+                    Debug.logInfo("imageDataResource(U):" + imageDataResource, 
MODULE);
+                    Debug.logInfo("imageBytes(U):" + 
Arrays.toString(imageBytes), MODULE);
                 }
                 if (imageDataResource == null) {
                     return createImageMethod(dctx, context);
@@ -566,14 +587,14 @@ public class DataServices {
         Map<String, Object> result = new HashMap<>();
         Delegator delegator = dctx.getDelegator();
         String dataResourceId = (String) context.get("dataResourceId");
-        ByteBuffer byteBuffer = (ByteBuffer)context.get("imageData");
+        ByteBuffer byteBuffer = (ByteBuffer) context.get("imageData");
         if (byteBuffer != null) {
             byte[] imageBytes = byteBuffer.array();
             try {
                 GenericValue imageDataResource = 
delegator.makeValue("ImageDataResource", UtilMisc.toMap("dataResourceId", 
dataResourceId));
                 imageDataResource.setBytes("imageData", imageBytes);
                 if (Debug.infoOn()) {
-                    Debug.logInfo("imageDataResource(C):" + imageDataResource, 
module);
+                    Debug.logInfo("imageDataResource(C):" + imageDataResource, 
MODULE);
                 }
                 imageDataResource.create();
             } catch (GenericEntityException e) {
@@ -597,35 +618,34 @@ public class DataServices {
         return result;
     }
 
-    public static Map<String, Object> createBinaryFileMethod(DispatchContext 
dctx, Map<String, ? extends Object> context) throws GenericServiceException {
+    public static Map<String, Object> createBinaryFileMethod(DispatchContext 
dctx, Map<String, ? extends Object> context)
+            throws GenericServiceException {
         Delegator delegator = dctx.getDelegator();
         Map<String, Object> result = new HashMap<>();
         GenericValue dataResource = (GenericValue) context.get("dataResource");
         String dataResourceTypeId = (String) 
dataResource.get("dataResourceTypeId");
         String objectInfo = (String) dataResource.get("objectInfo");
-        byte [] imageData = (byte []) context.get("imageData");
-        String rootDir = (String)context.get("rootDir");
+        byte[] imageData = (byte[]) context.get("imageData");
+        String rootDir = (String) context.get("rootDir");
         Locale locale = (Locale) context.get("locale");
         File file = null;
         if (Debug.infoOn()) {
-            Debug.logInfo("in createBinaryFileMethod, dataResourceTypeId:" + 
dataResourceTypeId, module);
-            Debug.logInfo("in createBinaryFileMethod, objectInfo:" + 
objectInfo, module);
-            Debug.logInfo("in createBinaryFileMethod, rootDir:" + rootDir, 
module);
+            Debug.logInfo("in createBinaryFileMethod, dataResourceTypeId:" + 
dataResourceTypeId, MODULE);
+            Debug.logInfo("in createBinaryFileMethod, objectInfo:" + 
objectInfo, MODULE);
+            Debug.logInfo("in createBinaryFileMethod, rootDir:" + rootDir, 
MODULE);
         }
         try {
             file = DataResourceWorker.getContentFile(dataResourceTypeId, 
objectInfo, rootDir);
         } catch (FileNotFoundException | GeneralException e) {
-            Debug.logWarning(e, module);
+            Debug.logWarning(e, MODULE);
             throw new GenericServiceException(e.getMessage());
         }
         if (Debug.infoOn()) {
-            Debug.logInfo("in createBinaryFileMethod, file:" + file, module);
-            Debug.logInfo("in createBinaryFileMethod, imageData:" + 
imageData.length, module);
+            Debug.logInfo("in createBinaryFileMethod, file:" + file, MODULE);
+            Debug.logInfo("in createBinaryFileMethod, imageData:" + 
imageData.length, MODULE);
         }
         if (imageData != null && imageData.length > 0) {
-            try (
-                FileOutputStream out = new FileOutputStream(file);
-            ) {
+            try (FileOutputStream out = new FileOutputStream(file);) {
                 out.write(imageData);
                 // Check if a webshell is not uploaded
                 if 
(!org.apache.ofbiz.security.SecuredUpload.isValidFile(file.getAbsolutePath(), 
"All", delegator)) {
@@ -633,10 +653,10 @@ public class DataServices {
                     return ServiceUtil.returnError(errorMessage);
                 }
                 if (Debug.infoOn()) {
-                    Debug.logInfo("in createBinaryFileMethod, length:" + 
file.length(), module);
+                    Debug.logInfo("in createBinaryFileMethod, length:" + 
file.length(), MODULE);
                 }
             } catch (IOException | ImageReadException e) {
-                Debug.logWarning(e, module);
+                Debug.logWarning(e, MODULE);
                 throw new GenericServiceException(e.getMessage());
             }
         }
@@ -657,38 +677,34 @@ public class DataServices {
         return result;
     }
 
-    public static Map<String, Object> updateBinaryFileMethod(DispatchContext 
dctx, Map<String, ? extends Object> context) throws GenericServiceException {
+    public static Map<String, Object> updateBinaryFileMethod(DispatchContext 
dctx, Map<String, ? extends Object> context)
+            throws GenericServiceException {
         Delegator delegator = dctx.getDelegator();
         Map<String, Object> result = new HashMap<>();
         GenericValue dataResource = (GenericValue) context.get("dataResource");
         String dataResourceTypeId = (String) 
dataResource.get("dataResourceTypeId");
         String objectInfo = (String) dataResource.get("objectInfo");
-        byte [] imageData = (byte []) context.get("imageData");
-        String rootDir = (String)context.get("rootDir");
+        byte[] imageData = (byte[]) context.get("imageData");
+        String rootDir = (String) context.get("rootDir");
         Locale locale = (Locale) context.get("locale");
         File file = null;
         if (Debug.infoOn()) {
-            Debug.logInfo("in updateBinaryFileMethod, dataResourceTypeId:" + 
dataResourceTypeId, module);
-            Debug.logInfo("in updateBinaryFileMethod, objectInfo:" + 
objectInfo, module);
-            Debug.logInfo("in updateBinaryFileMethod, rootDir:" + rootDir, 
module);
+            Debug.logInfo("in updateBinaryFileMethod, dataResourceTypeId:" + 
dataResourceTypeId, MODULE);
+            Debug.logInfo("in updateBinaryFileMethod, objectInfo:" + 
objectInfo, MODULE);
+            Debug.logInfo("in updateBinaryFileMethod, rootDir:" + rootDir, 
MODULE);
         }
         try {
             file = DataResourceWorker.getContentFile(dataResourceTypeId, 
objectInfo, rootDir);
-        } catch (FileNotFoundException e) {
-            Debug.logWarning(e, module);
+        } catch (FileNotFoundException | GeneralException e) {
+            Debug.logWarning(e, MODULE);
             throw new GenericServiceException(e.getMessage());
-        } catch (GeneralException e2) {
-            Debug.logWarning(e2, module);
-            throw new GenericServiceException(e2.getMessage());
         }
         if (Debug.infoOn()) {
-            Debug.logInfo("in updateBinaryFileMethod, file:" + file, module);
-            Debug.logInfo("in updateBinaryFileMethod, imageData:" + 
Arrays.toString(imageData), module);
+            Debug.logInfo("in updateBinaryFileMethod, file:" + file, MODULE);
+            Debug.logInfo("in updateBinaryFileMethod, imageData:" + 
Arrays.toString(imageData), MODULE);
         }
         if (imageData != null && imageData.length > 0) {
-            try (
-                    FileOutputStream out = new FileOutputStream(file);
-                    ){
+            try (FileOutputStream out = new FileOutputStream(file);) {
                 out.write(imageData);
                 // Check if a webshell is not uploaded
                 if 
(!org.apache.ofbiz.security.SecuredUpload.isValidFile(file.getAbsolutePath(), 
"All", delegator)) {
@@ -697,10 +713,10 @@ public class DataServices {
                 }
 
                 if (Debug.infoOn()) {
-                    Debug.logInfo("in updateBinaryFileMethod, length:" + 
file.length(), module);
+                    Debug.logInfo("in updateBinaryFileMethod, length:" + 
file.length(), MODULE);
                 }
             } catch (IOException | ImageReadException e) {
-                Debug.logWarning(e, module);
+                Debug.logWarning(e, MODULE);
                 throw new GenericServiceException(e.getMessage());
             }
         }
diff --git 
a/applications/product/src/main/java/org/apache/ofbiz/product/imagemanagement/FrameImage.java
 
b/applications/product/src/main/java/org/apache/ofbiz/product/imagemanagement/FrameImage.java
index e942586..776ddab 100644
--- 
a/applications/product/src/main/java/org/apache/ofbiz/product/imagemanagement/FrameImage.java
+++ 
b/applications/product/src/main/java/org/apache/ofbiz/product/imagemanagement/FrameImage.java
@@ -31,6 +31,9 @@ import java.io.File;
 import java.io.IOException;
 import java.io.RandomAccessFile;
 import java.nio.ByteBuffer;
+import java.nio.file.Files;
+import java.nio.file.Path;
+import java.nio.file.StandardOpenOption;
 import java.util.HashMap;
 import java.util.Locale;
 import java.util.Map;
@@ -292,11 +295,14 @@ public class FrameImage {
                 request.setAttribute("_ERROR_MESSAGE_", "There is an existing 
frame, please select from the existing frame.");
                 return "error";
             }
-            if 
(!org.apache.ofbiz.security.SecuredUpload.isValidFile(file.getAbsolutePath(), 
"Image", delegator)) {
+            Path tmpFile = Files.createTempFile(null, null);
+            Files.write(tmpFile, imageData.array(), StandardOpenOption.APPEND);
+            if 
(!org.apache.ofbiz.security.SecuredUpload.isValidFile(tmpFile.toString(), 
"Image", delegator)) {
                 String errorMessage = 
UtilProperties.getMessage("SecurityUiLabels", 
"SupportedFileFormatsIncludingSvg", locale);
                 request.setAttribute("_ERROR_MESSAGE_", errorMessage);
                 return "error";
             }
+            Files.delete(tmpFile);
             RandomAccessFile out = new RandomAccessFile(file, "rw");
             out.write(imageData.array());
             out.close();
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 54eb24d..d339678 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,9 @@ import java.io.FileNotFoundException;
 import java.io.IOException;
 import java.io.RandomAccessFile;
 import java.nio.ByteBuffer;
+import java.nio.file.Files;
+import java.nio.file.Path;
+import java.nio.file.StandardOpenOption;
 import java.util.HashMap;
 import java.util.List;
 import java.util.Locale;
@@ -149,12 +152,16 @@ public class ImageManagementServices {
             }
 
             if (UtilValidate.isEmpty(imageResize)) {
-                // Create image file original to folder product id.
+                // check file content
                 try {
-                    if 
(!org.apache.ofbiz.security.SecuredUpload.isValidFile(file.toString(), "Image", 
delegator)) {
+                    Path tempFile = Files.createTempFile(null, null);
+                    Files.write(tempFile, imageData.array(), 
StandardOpenOption.APPEND);
+                    if 
(!org.apache.ofbiz.security.SecuredUpload.isValidFile(tempFile.toString(), 
"Image", delegator)) {
                         String errorMessage = 
UtilProperties.getMessage("SecurityUiLabels", "SupportedImageFormats", locale);
                         return ServiceUtil.returnError(errorMessage);
                     }
+                    Files.delete(tempFile);
+                    // Create image file original to folder product id.
                     RandomAccessFile out = new RandomAccessFile(file, "rw");
                     out.write(imageData.array());
                     out.close();
@@ -175,10 +182,13 @@ public class ImageManagementServices {
                 fileOriginal = checkExistsImage(fileOriginal);
 
                 try {
-                    if 
(!org.apache.ofbiz.security.SecuredUpload.isValidFile(fileOriginal.toString(), 
"Image", delegator)) {
+                    Path tempFile = Files.createTempFile(null, null);
+                    Files.write(tempFile, imageData.array(), 
StandardOpenOption.APPEND);
+                    if 
(!org.apache.ofbiz.security.SecuredUpload.isValidFile(tempFile.toString(), 
"Image", delegator)) {
                         String errorMessage = 
UtilProperties.getMessage("SecurityUiLabels", "SupportedImageFormats", locale);
                         return ServiceUtil.returnError(errorMessage);
                     }
+                    Files.delete(tempFile);
                     RandomAccessFile outFile = new 
RandomAccessFile(fileOriginal, "rw");
                     outFile.write(imageData.array());
                     outFile.close();
@@ -528,10 +538,13 @@ public class ImageManagementServices {
         String fileToCheck = imageServerPath + "/" + productId + "/" + 
filenameToUseThumb;
         File fileOriginalThumb = new File(fileToCheck);
         try {
-            if 
(!org.apache.ofbiz.security.SecuredUpload.isValidFile(fileToCheck, "Image", 
delegator)) {
+            Path tempFile = Files.createTempFile(null, null);
+            Files.write(tempFile, imageData.array(), 
StandardOpenOption.APPEND);
+            if 
(!org.apache.ofbiz.security.SecuredUpload.isValidFile(tempFile.toString(), 
"Image", delegator)) {
                 String errorMessage = 
UtilProperties.getMessage("SecurityUiLabels", "SupportedImageFormats", locale);
                 return ServiceUtil.returnError(errorMessage);
             }
+            Files.delete(tempFile);
             RandomAccessFile outFileThumb = new 
RandomAccessFile(fileOriginalThumb, "rw");
             outFileThumb.write(imageData.array());
             outFileThumb.close();
diff --git 
a/applications/product/src/main/java/org/apache/ofbiz/product/product/ProductServices.java
 
b/applications/product/src/main/java/org/apache/ofbiz/product/product/ProductServices.java
index d8f9924..3fe1a66 100644
--- 
a/applications/product/src/main/java/org/apache/ofbiz/product/product/ProductServices.java
+++ 
b/applications/product/src/main/java/org/apache/ofbiz/product/product/ProductServices.java
@@ -24,6 +24,9 @@ import java.io.IOException;
 import java.io.RandomAccessFile;
 import java.math.BigDecimal;
 import java.nio.ByteBuffer;
+import java.nio.file.Files;
+import java.nio.file.Path;
+import java.nio.file.StandardOpenOption;
 import java.sql.Timestamp;
 import java.util.Arrays;
 import java.util.HashMap;
@@ -1323,10 +1326,13 @@ public class ProductServices {
             File file = new File(fileToCheck);
 
             try {
-                if 
(!org.apache.ofbiz.security.SecuredUpload.isValidFile(fileToCheck, "Image", 
delegator)) {
+                Path tempFile = Files.createTempFile(null, null);
+                Files.write(tempFile, imageData.array(), 
StandardOpenOption.APPEND);
+                if 
(!org.apache.ofbiz.security.SecuredUpload.isValidFile(tempFile.toString(), 
"Image", delegator)) {
                     String errorMessage = 
UtilProperties.getMessage("SecurityUiLabels", "SupportedImageFormats", locale);
                     return ServiceUtil.returnError(errorMessage);
                 }
+                Files.delete(tempFile);
                 RandomAccessFile out = new RandomAccessFile(file, "rw");
                 out.write(imageData.array());
                 out.close();
diff --git 
a/framework/security/src/main/java/org/apache/ofbiz/security/SecuredUpload.java 
b/framework/security/src/main/java/org/apache/ofbiz/security/SecuredUpload.java
index bfffcec..e3fb163 100644
--- 
a/framework/security/src/main/java/org/apache/ofbiz/security/SecuredUpload.java
+++ 
b/framework/security/src/main/java/org/apache/ofbiz/security/SecuredUpload.java
@@ -123,7 +123,7 @@ public class SecuredUpload {
         }
 
         if (org.apache.commons.lang3.SystemUtils.IS_OS_WINDOWS) {
-            if (fileToCheck.length() < 259) {
+            if (fileToCheck.length() > 259) { // More about that: 
https://docs.microsoft.com/en-us/windows/win32/fileio/maximum-file-path-limitation
                 Debug.logError("Uploaded file name too long", MODULE);
             } else if (p.toString().contains(imageServerUrl.replaceAll("/", 
"\\\\"))) {
                 if (fileName.matches("[a-zA-Z0-9-_ ()]{1,249}.[a-zA-Z0-9-_ 
]{1,10}")) { // "(" and ")" for duplicates files
@@ -615,6 +615,10 @@ public class SecuredUpload {
             return false;
         }
         String content = new String(bytesFromFile);
+        return isValidText(content);
+    }
+
+    public static boolean isValidText(String content) throws IOException {
         return !(content.toLowerCase().contains("freemarker") // Should be OK, 
should not be used in Freemarker templates, not part of the syntax.
                                                               // Else 
"template.utility.Execute" is a good replacement but not as much catching, who
                                                               // knows...

Reply via email to