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

heneveld pushed a commit to branch master
in repository https://gitbox.apache.org/repos/asf/brooklyn-server.git

commit e1373b5143a1bce621c7b6582b3524793e51ec44
Author: Juan Cabrerizo <[email protected]>
AuthorDate: Mon Nov 28 20:41:03 2022 +0000

    prevent to extract files outside the scoped `targetFolder`
---
 .../brooklyn/util/core/file/ArchiveUtils.java      | 31 +++++++++++++++++-----
 1 file changed, 24 insertions(+), 7 deletions(-)

diff --git 
a/core/src/main/java/org/apache/brooklyn/util/core/file/ArchiveUtils.java 
b/core/src/main/java/org/apache/brooklyn/util/core/file/ArchiveUtils.java
index 1a5dc08a1f..1a374d28e2 100644
--- a/core/src/main/java/org/apache/brooklyn/util/core/file/ArchiveUtils.java
+++ b/core/src/main/java/org/apache/brooklyn/util/core/file/ArchiveUtils.java
@@ -363,21 +363,38 @@ public class ArchiveUtils {
     }
 
     public static void extractZip(final ZipFile zip, final String 
targetFolder) {
-        new File(targetFolder).mkdir();
+        File targetPath = new File(targetFolder);
+        targetPath.mkdir();
         Enumeration<? extends ZipEntry> zipFileEntries = zip.entries();
         while (zipFileEntries.hasMoreElements()) {
-            ZipEntry entry = (ZipEntry) zipFileEntries.nextElement();
-            File destFile = new File(targetFolder, entry.getName());
+            ZipEntry entry = zipFileEntries.nextElement();
+            String originalName = entry.getName();
+            File destFile = new File(targetPath, originalName);
+            // validate input path
+            try {
+                String canonicalDestinationDirPath = null;
+                // enforce the file uses the appropriate file separator for 
the controller SO
+                String sanitizedName = originalName
+                        .replace("\\", File.separator)
+                        .replace("/", File.separator);
+                File sanitizedDestFile = new File(targetPath, sanitizedName);
+                canonicalDestinationDirPath = targetPath.getCanonicalPath();
+                String canonicalDestinationFile = 
sanitizedDestFile.getCanonicalPath();
+                if 
(!canonicalDestinationFile.startsWith(canonicalDestinationDirPath + 
File.separator)) {
+                    throw new IllegalStateException("Entry is outside of the 
target dir: " + entry.getName());
+                }
+            } catch (IOException e) {
+                throw Exceptions.propagate(e);
+            }
             destFile.getParentFile().mkdirs();
-
             if (!entry.isDirectory()) {
-                try (InputStream in=zip.getInputStream(entry); OutputStream 
out=new FileOutputStream(destFile)) {
+                try (InputStream in = zip.getInputStream(entry); OutputStream 
out = new FileOutputStream(destFile)) {
                     Streams.copy(in, out);
-                } catch (IOException e) {
+                }
+                catch (IOException e) {
                     throw Exceptions.propagate(e);
                 }
             }
         }
     }
-    
 }

Reply via email to