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

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


The following commit(s) were added to refs/heads/trunk by this push:
     new 3c9cd71  Fixed: Secure the uploads (OFBIZ-12080)
3c9cd71 is described below

commit 3c9cd7139ac02b84eb2c3b0fbc06b5a21d4492d1
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   | 49 +++++++++++-----------
 .../ofbiz/service/engine/GroovyBaseScript.groovy   | 20 ++++++---
 3 files changed, 58 insertions(+), 32 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 b93320a..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;
@@ -158,24 +147,24 @@ public class SecuredUpload {
                 } else if 
(p.toString().contains(imageServerUrl.replaceAll("/", "\\\\"))) {
                     // TODO check this is still useful in at least 1 case
                     if (fileName.matches("[a-zA-Z0-9-_ ()]{1,249}.[a-zA-Z0-9-_ 
]{1,10}")) { // "(" and ")" for duplicates files
+                        wrongFile = false;
+                    }
+                } else if (fileName.matches("[a-zA-Z0-9-_ 
]{1,249}.[a-zA-Z0-9-_ ]{1,10}")) {
                     wrongFile = false;
                 }
-            } else if (fileName.matches("[a-zA-Z0-9-_ ]{1,249}.[a-zA-Z0-9-_ 
]{1,10}")) {
-                wrongFile = false;
-            }
-        } else { // Suppose a *nix system
-            if (fileToCheck.length() > 4096) {
-                Debug.logError("Uploaded file name too long", MODULE);
-            } else if (p.toString().contains(imageServerUrl)) {
+            } else { // Suppose a *nix system
+                if (fileToCheck.length() > 4096) {
+                    Debug.logError("Uploaded file name too long", MODULE);
+                } else if (p.toString().contains(imageServerUrl)) {
                     // TODO check this is still useful in at least 1 case
-                if (fileName.matches("[a-zA-Z0-9-_ ()]{1,4086}.[a-zA-Z0-9-_ 
]{1,10}")) { // "(" and ")" for duplicates files
+                    if (fileName.matches("[a-zA-Z0-9-_ 
()]{1,4086}.[a-zA-Z0-9-_ ]{1,10}")) { // "(" and ")" for duplicates files
+                        wrongFile = false;
+                    }
+                } else if (fileName.matches("[a-zA-Z0-9-_ 
]{1,4086}.[a-zA-Z0-9-_ ]{1,10}")) {
                     wrongFile = false;
                 }
-            } else if (fileName.matches("[a-zA-Z0-9-_ ]{1,4086}.[a-zA-Z0-9-_ 
]{1,10}")) {
-                wrongFile = false;
             }
         }
-    }
 
         if (wrongFile) {
             Debug.logError("Uploaded file "
@@ -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;
@@ -385,7 +386,7 @@ public class SecuredUpload {
                 safeState = true;
             } catch (IOException | ImageReadException | ImageWriteException e) 
{
                 Debug.logWarning(e, "Error during Image file " + fileName + " 
processing !", MODULE);
-        }
+            }
         }
         return safeState;
     }
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