diff --git a/knowage-api/src/main/java/it/eng/knowage/resourcemanager/service/impl/ResourceManagerAPIImpl.java b/knowage-api/src/main/java/it/eng/knowage/resourcemanager/service/impl/ResourceManagerAPIImpl.java index 3c4c6850630..4bf9e9d6a18 100644 --- a/knowage-api/src/main/java/it/eng/knowage/resourcemanager/service/impl/ResourceManagerAPIImpl.java +++ b/knowage-api/src/main/java/it/eng/knowage/resourcemanager/service/impl/ResourceManagerAPIImpl.java @@ -546,6 +546,10 @@ private void extractFolder(String zipFile, String extractFolder) throws IOExcept String newPath = extractFolder; new File(newPath).mkdir(); + + // Get canonical path for security validation + String extractDirCanonicalPath = extractDir.getCanonicalPath(); + Enumeration zipFileEntries = zip.entries(); // Process each entry @@ -555,6 +559,14 @@ private void extractFolder(String zipFile, String extractFolder) throws IOExcept String currentEntry = entry.getName(); File destFile = new File(newPath, currentEntry); + + // Security check: Prevent Zip Slip vulnerability + String destFileCanonicalPath = destFile.getCanonicalPath(); + if (!destFileCanonicalPath.startsWith(extractDirCanonicalPath + File.separator) && + !destFileCanonicalPath.equals(extractDirCanonicalPath)) { + throw new IOException("Entry is outside of the target dir: " + currentEntry); + } + File destinationParent = destFile.getParentFile(); // create the parent directory structure if needed diff --git a/knowageutils/src/main/java/it/eng/spagobi/commons/utilities/ZipUtils.java b/knowageutils/src/main/java/it/eng/spagobi/commons/utilities/ZipUtils.java index 4f1e90b6ecd..40f4f2688f1 100644 --- a/knowageutils/src/main/java/it/eng/spagobi/commons/utilities/ZipUtils.java +++ b/knowageutils/src/main/java/it/eng/spagobi/commons/utilities/ZipUtils.java @@ -242,6 +242,12 @@ private static void unzip(String zipFileName, InputStream zipFile, File outFolde if (entry.isDirectory()) { Path path = Paths.get(outFolder.getPath(), entry.getName()); + + // Security check: Prevent Zip Slip attack + if (!path.normalize().startsWith(outFolder.toPath().normalize())) { + throw new IOException("Entry is outside of the target dir: " + entry.getName()); + } + Files.createDirectories(path); } else { @@ -252,9 +258,17 @@ private static void unzip(String zipFileName, InputStream zipFile, File outFolde Path path = Paths.get(outFolder.getPath(), (prependZipFileName ? zipFileName + "_" : "") + entry.getName()); + // Security check: Prevent Zip Slip attack + if (!path.normalize().startsWith(outFolder.toPath().normalize())) { + throw new IOException("Entry is outside of the target dir: " + entry.getName()); + } + if (Files.exists(path)) throw new ZipException("File already exists: " + path); + // Ensure parent directories exist + Files.createDirectories(path.getParent()); + // write the files to the disk try (OutputStream os = Files.newOutputStream(path); BufferedOutputStream out = new BufferedOutputStream(os, 1000)) {