You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@pulsar.apache.org by mm...@apache.org on 2024/06/04 02:31:21 UTC

(pulsar) branch master updated: [improve] Validate user paths in Functions utils (#22833)

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

mmerli pushed a commit to branch master
in repository https://gitbox.apache.org/repos/asf/pulsar.git


The following commit(s) were added to refs/heads/master by this push:
     new ca8b465897f [improve] Validate user paths in Functions utils (#22833)
ca8b465897f is described below

commit ca8b465897fd6176b614e2b3f2a841b349037aad
Author: Matteo Merli <mm...@apache.org>
AuthorDate: Mon Jun 3 19:31:15 2024 -0700

    [improve] Validate user paths in Functions utils (#22833)
---
 .../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 ee59317daf7..9dc9d5428ed 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
@@ -853,14 +853,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