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

pgil 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 c0f8783  Improved: Create a deny list to reject webshell tokens 
(OFBIZ-12324)
c0f8783 is described below

commit c0f8783d8d5d4fe90f67c8c82da3950daafc4a25
Author: Gil Portenseigne <p...@apache.org>
AuthorDate: Wed Sep 22 15:03:30 2021 +0200

    Improved: Create a deny list to reject webshell tokens (OFBIZ-12324)
    
    Improve readability using stream api, while adding unit test for
    refactoring validation.
    Fix deniedWebShellTokens property where some blank space where removed
    and '// python' comment was inlined.
---
 framework/security/config/security.properties      |  4 +-
 .../org/apache/ofbiz/security/SecuredUpload.java   | 26 ++-----------
 .../apache/ofbiz/security/SecurityUtilTest.java    | 45 ++++++++++++++++++++++
 3 files changed, 51 insertions(+), 24 deletions(-)

diff --git a/framework/security/config/security.properties 
b/framework/security/config/security.properties
index 08433a4..5816f0c 100644
--- a/framework/security/config/security.properties
+++ b/framework/security/config/security.properties
@@ -238,7 +238,9 @@ allowAllUploads=
 #-- eg: 
https://www.acunetix.com/blog/articles/detection-prevention-introduction-web-shells-part-5/
 #-- "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...
-deniedWebShellTokens=freemarker,import=\"java,runtime.getruntime().exec(,<%@page,<script,<body>,<form,php,javascript,%eval,@eval,importos//Python,passthru,exec,shell_exec,assert,str_rot13,system,phpinfo,base64_decode,chmod,mkdir,fopen,fclose,newfile,import,upload,getfilename,download,getoutputstring,readfile
+deniedWebShellTokens=freemarker,import=\"java,runtime.getruntime().exec(,<%@ 
page,<script,<body>,<form,php,\
+  javascript,%eval,@eval,import 
os,passthru,exec,shell_exec,assert,str_rot13,system,phpinfo,base64_decode,chmod,mkdir,\
+  fopen,fclose,new 
file,import,upload,getfilename,download,getoutputstring,readfile
 
 #-- Popup last-visited time from database after user has logged in.
 #-- So users can know of any unauthorised access to their accounts.
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 6741975..05f784d 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
@@ -39,7 +39,6 @@ import java.util.Collection;
 import java.util.HashMap;
 import java.util.HashSet;
 import java.util.Iterator;
-import java.util.LinkedList;
 import java.util.List;
 import java.util.Set;
 import java.util.UUID;
@@ -616,12 +615,7 @@ public class SecuredUpload {
     }
 
     public static boolean isValidText(String content, List<String> allowed) 
throws IOException {
-        for (String token : DENIEDWEBSHELLTOKENS) {
-            if (!isValid(content, token, allowed)) {
-                return false;
-            }
-        }
-        return true;
+        return DENIEDWEBSHELLTOKENS.stream().allMatch(token -> 
isValid(content, token, allowed));
     }
 
     private static boolean isValid(String content, String string, List<String> 
allowed) {
@@ -637,26 +631,12 @@ public class SecuredUpload {
     }
 
     private static List<String> deniedFileExtensions() {
-        List<String> deniedFileExtensions = new LinkedList<>();
         String deniedExtensions = UtilProperties.getPropertyValue("security", 
"deniedFileExtensions");
-        if (UtilValidate.isNotEmpty(deniedExtensions)) {
-            List<String> deniedFileExtensionsList = 
StringUtil.split(deniedExtensions, ",");
-            for (String deniedExtension : deniedFileExtensionsList) {
-                deniedFileExtensions.add(deniedExtension);
-            }
-        }
-        return deniedFileExtensions;
+        return UtilValidate.isNotEmpty(deniedExtensions) ? 
StringUtil.split(deniedExtensions, ",") : new ArrayList<>();
     }
 
     private static List<String> deniedWebShellTokens() {
-        List<String> deniedWebShellTokens = new LinkedList<>();
         String deniedTokens = UtilProperties.getPropertyValue("security", 
"deniedWebShellTokens");
-        if (UtilValidate.isNotEmpty(deniedTokens)) {
-            List<String> deniedWebShellTokensList = 
StringUtil.split(deniedTokens, ",");
-            for (String deniedToken : deniedWebShellTokensList) {
-                deniedWebShellTokens.add(deniedToken);
-            }
-        }
-        return deniedWebShellTokens;
+        return UtilValidate.isNotEmpty(deniedTokens) ? 
StringUtil.split(deniedTokens, ",") : new ArrayList<>();
     }
 }
diff --git 
a/framework/security/src/test/java/org/apache/ofbiz/security/SecurityUtilTest.java
 
b/framework/security/src/test/java/org/apache/ofbiz/security/SecurityUtilTest.java
index 47b8bb6..4a11e91 100644
--- 
a/framework/security/src/test/java/org/apache/ofbiz/security/SecurityUtilTest.java
+++ 
b/framework/security/src/test/java/org/apache/ofbiz/security/SecurityUtilTest.java
@@ -18,6 +18,8 @@
  */
 package org.apache.ofbiz.security;
 
+import java.io.IOException;
+import java.util.ArrayList;
 import java.util.Arrays;
 import java.util.List;
 
@@ -25,6 +27,7 @@ import org.junit.Test;
 
 import static org.junit.Assert.assertTrue;
 import static org.junit.Assert.assertFalse;
+import static org.junit.Assert.fail;
 
 public class SecurityUtilTest {
     @Test
@@ -52,4 +55,46 @@ public class SecurityUtilTest {
                     adminPermissions, "SPECIFIC_MULTI_LEVEL_EXAMPLE_VIEW"));
         
assertFalse(SecurityUtil.checkMultiLevelAdminPermissionValidity(adminPermissions,
 "HOTDEP_PARTYMGR_ADMIN"));
     }
+
+    @Test
+    public void webShellTokensTesting() {
+        try {
+            assertTrue(SecuredUpload.isValidText("hack.getFileName", 
List.of("getfilename")));
+            List<String> allowed = new ArrayList<>();
+            assertFalse(SecuredUpload.isValidText("hack.getFileName", 
allowed));
+            assertFalse(SecuredUpload.isValidText("freemarker", allowed));
+            assertFalse(SecuredUpload.isValidText("import=\"java", allowed));
+            
assertFalse(SecuredUpload.isValidText("runtime.getruntime().exec(", allowed));
+            assertFalse(SecuredUpload.isValidText("<%@ page", allowed));
+            assertFalse(SecuredUpload.isValidText("<script", allowed));
+            assertFalse(SecuredUpload.isValidText("<body>", allowed));
+            assertFalse(SecuredUpload.isValidText("<form", allowed));
+            assertFalse(SecuredUpload.isValidText("php", allowed));
+            assertFalse(SecuredUpload.isValidText("javascript", allowed));
+            assertFalse(SecuredUpload.isValidText("%eval", allowed));
+            assertFalse(SecuredUpload.isValidText("@eval", allowed));
+            assertFalse(SecuredUpload.isValidText("import os", allowed));
+            assertFalse(SecuredUpload.isValidText("passthru", allowed));
+            assertFalse(SecuredUpload.isValidText("exec", allowed));
+            assertFalse(SecuredUpload.isValidText("shell_exec", allowed));
+            assertFalse(SecuredUpload.isValidText("assert", allowed));
+            assertFalse(SecuredUpload.isValidText("str_rot13", allowed));
+            assertFalse(SecuredUpload.isValidText("system", allowed));
+            assertFalse(SecuredUpload.isValidText("phpinfo", allowed));
+            assertFalse(SecuredUpload.isValidText("base64_decode", allowed));
+            assertFalse(SecuredUpload.isValidText("chmod", allowed));
+            assertFalse(SecuredUpload.isValidText("mkdir", allowed));
+            assertFalse(SecuredUpload.isValidText("fopen", allowed));
+            assertFalse(SecuredUpload.isValidText("fclose", allowed));
+            assertFalse(SecuredUpload.isValidText("new file", allowed));
+            assertFalse(SecuredUpload.isValidText("import", allowed));
+            assertFalse(SecuredUpload.isValidText("upload", allowed));
+            assertFalse(SecuredUpload.isValidText("getfilename", allowed));
+            assertFalse(SecuredUpload.isValidText("download", allowed));
+            assertFalse(SecuredUpload.isValidText("getoutputstring", allowed));
+            assertFalse(SecuredUpload.isValidText("readfile", allowed));
+        } catch (IOException e) {
+            fail(String.format("IOException occured : %s", e.getMessage()));
+        }
+    }
 }

Reply via email to