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

lhotari pushed a commit to branch branch-3.0
in repository https://gitbox.apache.org/repos/asf/pulsar.git

commit b4b69c8ba8695347000c9fcca2b878159efc359d
Author: Matteo Merli <[email protected]>
AuthorDate: Mon Jun 3 19:31:15 2024 -0700

    [improve] Validate user paths in Functions utils (#22833)
    
    (cherry picked from commit ca8b465897fd6176b614e2b3f2a841b349037aad)
---
 .../apache/pulsar/broker/web/ExceptionHandler.java |  2 ++
 .../functions/utils/FunctionConfigUtils.java       | 14 ++++++--
 .../filesystem/FileSystemPackagesStorage.java      | 42 +++++++++++++++-------
 3 files changed, 43 insertions(+), 15 deletions(-)

diff --git 
a/pulsar-broker/src/main/java/org/apache/pulsar/broker/web/ExceptionHandler.java
 
b/pulsar-broker/src/main/java/org/apache/pulsar/broker/web/ExceptionHandler.java
index b11ec3a8a98..205e02ed75a 100644
--- 
a/pulsar-broker/src/main/java/org/apache/pulsar/broker/web/ExceptionHandler.java
+++ 
b/pulsar-broker/src/main/java/org/apache/pulsar/broker/web/ExceptionHandler.java
@@ -24,6 +24,7 @@ import java.nio.charset.StandardCharsets;
 import javax.servlet.ServletResponse;
 import javax.servlet.http.HttpServletResponse;
 import javax.ws.rs.core.Response;
+import lombok.extern.slf4j.Slf4j;
 import org.apache.pulsar.common.intercept.InterceptException;
 import org.apache.pulsar.common.policies.data.ErrorData;
 import org.apache.pulsar.common.util.ObjectMapperFactory;
@@ -36,6 +37,7 @@ import org.eclipse.jetty.http.MetaData;
 /**
  *  Exception handler for handle exception.
  */
+@Slf4j
 public class ExceptionHandler {
 
     public void handle(ServletResponse response, Exception ex) throws 
IOException {
diff --git 
a/pulsar-functions/utils/src/main/java/org/apache/pulsar/functions/utils/FunctionConfigUtils.java
 
b/pulsar-functions/utils/src/main/java/org/apache/pulsar/functions/utils/FunctionConfigUtils.java
index d7295d133da..ad6029f78cc 100644
--- 
a/pulsar-functions/utils/src/main/java/org/apache/pulsar/functions/utils/FunctionConfigUtils.java
+++ 
b/pulsar-functions/utils/src/main/java/org/apache/pulsar/functions/utils/FunctionConfigUtils.java
@@ -864,14 +864,24 @@ public class FunctionConfigUtils {
         if (!isEmpty(functionConfig.getPy()) && 
!org.apache.pulsar.common.functions.Utils
                 .isFunctionPackageUrlSupported(functionConfig.getPy())
                 && functionConfig.getPy().startsWith(BUILTIN)) {
-            if (!new File(functionConfig.getPy()).exists()) {
+            String filename = functionConfig.getPy();
+            if (filename.contains("..")) {
+                throw new IllegalArgumentException("Invalid filename: " + 
filename);
+            }
+
+            if (!new File(filename).exists()) {
                 throw new IllegalArgumentException("The supplied python file 
does not exist");
             }
         }
         if (!isEmpty(functionConfig.getGo()) && 
!org.apache.pulsar.common.functions.Utils
                 .isFunctionPackageUrlSupported(functionConfig.getGo())
                 && functionConfig.getGo().startsWith(BUILTIN)) {
-            if (!new File(functionConfig.getGo()).exists()) {
+            String filename = functionConfig.getGo();
+            if (filename.contains("..")) {
+                throw new IllegalArgumentException("Invalid filename: " + 
filename);
+            }
+
+            if (!new File(filename).exists()) {
                 throw new IllegalArgumentException("The supplied go file does 
not exist");
             }
         }
diff --git 
a/pulsar-package-management/filesystem-storage/src/main/java/org/apache/pulsar/packages/management/storage/filesystem/FileSystemPackagesStorage.java
 
b/pulsar-package-management/filesystem-storage/src/main/java/org/apache/pulsar/packages/management/storage/filesystem/FileSystemPackagesStorage.java
index 47d825ea928..2bb43bb2072 100644
--- 
a/pulsar-package-management/filesystem-storage/src/main/java/org/apache/pulsar/packages/management/storage/filesystem/FileSystemPackagesStorage.java
+++ 
b/pulsar-package-management/filesystem-storage/src/main/java/org/apache/pulsar/packages/management/storage/filesystem/FileSystemPackagesStorage.java
@@ -58,7 +58,11 @@ public class FileSystemPackagesStorage implements 
PackagesStorage {
         }
     }
 
-    private File getPath(String path) {
+    private File getPath(String path) throws IOException {
+        if (path.contains("..")) {
+            throw new IOException("Invalid path: " + path);
+        }
+
         File f = Paths.get(storagePath.toString(), path).toFile();
         if (!f.getParentFile().exists()) {
             if (!f.getParentFile().mkdirs()) {
@@ -119,28 +123,40 @@ public class FileSystemPackagesStorage implements 
PackagesStorage {
 
     @Override
     public CompletableFuture<Void> deleteAsync(String path) {
-        if (getPath(path).delete()) {
-            return CompletableFuture.completedFuture(null);
-        } else {
-            CompletableFuture<Void> f = new CompletableFuture<>();
-            f.completeExceptionally(new IOException("Failed to delete file at 
" + path));
-            return f;
+        try {
+            if (getPath(path).delete()) {
+                return CompletableFuture.completedFuture(null);
+            } else {
+                CompletableFuture<Void> f = new CompletableFuture<>();
+                f.completeExceptionally(new IOException("Failed to delete file 
at " + path));
+                return f;
+            }
+        } catch (IOException e) {
+            return CompletableFuture.failedFuture(e);
         }
     }
 
     @Override
     public CompletableFuture<List<String>> listAsync(String path) {
-        String[] files = getPath(path).list();
-        if (files == null) {
-            return CompletableFuture.completedFuture(Collections.emptyList());
-        } else {
-            return CompletableFuture.completedFuture(Arrays.asList(files));
+        try {
+            String[] files = getPath(path).list();
+            if (files == null) {
+                return 
CompletableFuture.completedFuture(Collections.emptyList());
+            } else {
+                return CompletableFuture.completedFuture(Arrays.asList(files));
+            }
+        } catch (IOException e) {
+            return CompletableFuture.failedFuture(e);
         }
     }
 
     @Override
     public CompletableFuture<Boolean> existAsync(String path) {
-        return CompletableFuture.completedFuture(getPath(path).exists());
+        try {
+            return CompletableFuture.completedFuture(getPath(path).exists());
+        } catch (IOException e) {
+            return CompletableFuture.failedFuture(e);
+        }
     }
 
     @Override

Reply via email to