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

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

commit 4d70280cb86c65a096b71b560623d33bc563e960
Author: Jacques Le Roux <jacques.le.r...@les7arts.com>
AuthorDate: Sun Feb 20 15:39:11 2022 +0100

    Fixed: Secure the uploads (OFBIZ-12080)
    
    Last commits put in an issue in DataServices.java and 
GroovyBaseScript.groovy.
    I should have used SecuredUpload::isValidFileName with dataResourceName and
    SecuredUpload::isValidFile  with objectInfo. This fixes that.
    
    Also fixes formatting checkstyle issues in SecuredUpload class.
    
    Also fixes formatting checkstyle issues in SecuredUpload class and move 
allow
    all and check line length in right places (it's about content)
---
 .../apache/ofbiz/content/data/DataServices.java    | 21 +++++++++++++++---
 .../org/apache/ofbiz/security/SecuredUpload.java   | 25 +++++++++++-----------
 .../ofbiz/service/engine/GroovyBaseScript.groovy   | 20 ++++++++++++-----
 3 files changed, 46 insertions(+), 20 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 2bd71c1..cec71ac 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
@@ -199,12 +199,27 @@ public class DataServices {
     public static Map<String, Object> createFileNoPerm(DispatchContext dctx, 
Map<String, ? extends Object> rcontext) throws IOException,
             ImageReadException {
         String originalFileName = (String) rcontext.get("dataResourceName");
+        String fileNameAndPath = (String) rcontext.get("objectInfo");
         Delegator delegator = dctx.getDelegator();
         Locale locale = (Locale) rcontext.get("locale");
-        if (!SecuredUpload.isValidFile(originalFileName, "All", delegator)) {
-            String errorMessage = 
UtilProperties.getMessage("SecurityUiLabels", "SupportedTextFileFormats", 
locale);
-            return ServiceUtil.returnError(errorMessage);
+        File file = new File(fileNameAndPath);
+        if (!originalFileName.isEmpty()) {
+            // Check the file name
+            if 
(!org.apache.ofbiz.security.SecuredUpload.isValidFileName(originalFileName, 
delegator)) {
+                String errorMessage = 
UtilProperties.getMessage("SecurityUiLabels", 
"SupportedFileFormatsIncludingSvg", locale);
+                return ServiceUtil.returnError(errorMessage);
+            }
+            // TODO we could verify the file type (here "All") with 
dataResourceTypeId. Anyway it's done with isValidFile()
+            // We would just have a better error message
+            if (file.exists()) {
+                // Check if a webshell is not uploaded
+                if 
(!org.apache.ofbiz.security.SecuredUpload.isValidFile(fileNameAndPath, "All", 
delegator)) {
+                    String errorMessage = 
UtilProperties.getMessage("SecurityUiLabels", 
"SupportedFileFormatsIncludingSvg", locale);
+                    return ServiceUtil.returnError(errorMessage);
+                }
+            }
         }
+
         Map<String, Object> context = UtilMisc.makeMapWritable(rcontext);
         context.put("skipPermissionCheck", "true");
         return createFileMethod(dctx, context);
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 563d6cb..029db47 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
@@ -108,23 +108,12 @@ public class SecuredUpload {
     }
 
     public static boolean isValidFileName(String fileToCheck, Delegator 
delegator) throws IOException {
-        // Allow all
-        if 
(("true".equalsIgnoreCase(EntityUtilProperties.getPropertyValue("security", 
"allowAllUploads", delegator)))) {
-            return true;
-        }
-
         // Prevents double extensions
         if (StringUtils.countMatches(fileToCheck, ".") > 1) {
             Debug.logError("Double extensions are not allowed for security 
reason", MODULE);
             return false;
         }
 
-        // Check max line length, default 10000
-        if (!checkMaxLinesLength(fileToCheck)) {
-            Debug.logError("For security reason lines over " + 
MAXLINELENGTH.toString() + " are not allowed", MODULE);
-            return false;
-        }
-
         String imageServerUrl = 
EntityUtilProperties.getPropertyValue("catalog", "image.management.url", 
delegator);
         Path p = Paths.get(fileToCheck);
         boolean wrongFile = true;
@@ -197,12 +186,24 @@ public class SecuredUpload {
      * @throws ImageReadException
      */
     public static boolean isValidFile(String fileToCheck, String fileType, 
Delegator delegator) throws IOException, ImageReadException {
+        // Allow all
+        if 
(("true".equalsIgnoreCase(EntityUtilProperties.getPropertyValue("security", 
"allowAllUploads", delegator)))) {
+            return true;
+        }
 
+        // Check the file name
         if (!isValidFileName(fileToCheck, delegator)) {
             return false;
         }
 
-        // Check the the file content
+        // Check the file content
+
+        // Check max line length, default 10000
+        if (!checkMaxLinesLength(fileToCheck)) {
+            Debug.logError("For security reason lines over " + 
MAXLINELENGTH.toString() + " are not allowed", MODULE);
+            return false;
+        }
+
         if (isExecutable(fileToCheck)) {
             deleteBadFile(fileToCheck);
             return false;
diff --git 
a/framework/service/src/main/groovy/org/apache/ofbiz/service/engine/GroovyBaseScript.groovy
 
b/framework/service/src/main/groovy/org/apache/ofbiz/service/engine/GroovyBaseScript.groovy
index 377b05d..0c338f8 100644
--- 
a/framework/service/src/main/groovy/org/apache/ofbiz/service/engine/GroovyBaseScript.groovy
+++ 
b/framework/service/src/main/groovy/org/apache/ofbiz/service/engine/GroovyBaseScript.groovy
@@ -54,14 +54,24 @@ abstract class GroovyBaseScript extends Script {
                     : this.binding.getVariable('parameters').locale
         }
         if (serviceName.equals("createAnonFile")) {
-            String dataResourceName = inputMap.get("dataResourceName")
-            File file = new File(dataResourceName)
-            if (file.exists()) {
-                // Check if a webshell is not uploaded
-                if 
(!org.apache.ofbiz.security.SecuredUpload.isValidFile(dataResourceName, "All", 
delegator)) {
+            String fileName = inputMap.get("dataResourceName")
+            String fileNameAndPath = inputMap.get("objectInfo")
+            File file = new File(fileNameAndPath)
+            if (!fileName.isEmpty()) {
+                // Check the file name
+                if 
(!org.apache.ofbiz.security.SecuredUpload.isValidFileName(fileName, delegator)) 
{
                     String errorMessage = 
UtilProperties.getMessage("SecurityUiLabels", 
"SupportedFileFormatsIncludingSvg", inputMap.locale)
                     throw new ExecutionServiceException(errorMessage)
                 }
+                // TODO we could verify the file type (here "All") with 
dataResourceTypeId. Anyway it's done with isValidFile()
+                // We would just have a better error message
+                if (file.exists()) {
+                    // Check if a webshell is not uploaded
+                    if 
(!org.apache.ofbiz.security.SecuredUpload.isValidFile(fileNameAndPath, "All", 
delegator)) {
+                        String errorMessage = 
UtilProperties.getMessage("SecurityUiLabels", 
"SupportedFileFormatsIncludingSvg", inputMap.locale)
+                        throw new ExecutionServiceException(errorMessage)
+                    }
+                }
             }
         }
         Map serviceContext = dctx.makeValidContext(serviceName, 
ModelService.IN_PARAM, inputMap)

Reply via email to