From d6ea5e4838a0e2366ba41fb0546802a45fb0df11 Mon Sep 17 00:00:00 2001 From: teresa Date: Thu, 31 Jul 2025 00:29:11 +0800 Subject: [PATCH 1/2] Fix Zip Slip vulnerability Description: The ziputils method is vulnerable to Zip Slip attacks, allowing malicious ZIP files to extract files outside the intended directory through path traversal sequences like Downloads. This could lead to arbitrary file write vulnerabilities. Changes: Add path traversal validation using path.normalize().startsWith(outFolder.toPath().normalize()) Throw IOException when entries attempt to escape the target directory Add parent directory creation for extracted files Maintain existing functionality while preventing directory traversal attacks Security Impact: Prevents Zip Slip attacks that could allow attackers to overwrite arbitrary files on the filesystem, potentially leading to code execution or system compromise. References: https://github.com/naver/ngrinder/commit/700eb9f7ed2433cfc09c17320812d505b773a4cb https://cwe.mitre.org/data/definitions/22.html --- .../it/eng/spagobi/commons/utilities/ZipUtils.java | 14 ++++++++++++++ 1 file changed, 14 insertions(+) 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 4f1e90b6ec..40f4f2688f 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)) { From 69fdf79a9e5f58bd52bf272a8341c9c1048d9292 Mon Sep 17 00:00:00 2001 From: teresa Date: Thu, 31 Jul 2025 00:31:28 +0800 Subject: [PATCH 2/2] Fix Zip Slip Vulnerability Description Fixes a critical security vulnerability where malicious ZIP files could write files outside the intended extraction directory (Zip Slip attack). Changes Added path traversal validation using canonical paths Prevents extraction of entries that would write outside the target directory Throws IOException for malicious zip entries attempting directory traversal Security Impact Prevents arbitrary file write attacks Protects against malicious ZIP files containing path traversal sequences like Downloads Maintains functionality while ensuring extracted files remain within the intended directory References: https://github.com/naver/ngrinder/commit/700eb9f7ed2433cfc09c17320812d505b773a4cb https://cwe.mitre.org/data/definitions/22.html --- .../service/impl/ResourceManagerAPIImpl.java | 12 ++++++++++++ 1 file changed, 12 insertions(+) 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 3c4c685063..4bf9e9d6a1 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