CVE-2022-21675: Improper Limitation of a Pathname to a Restricted Directory ('Path Traversal') (CWE-22)
value: Bytecode Viewer (BCV) is a Java/Android reverse engineering suite. Versions of the package prior to 2.11.0 are vulnerable to Arbitrary File Write via Archive Extraction (AKA "Zip Slip"). The vulnerability is exploited using a specially crafted archive that holds directory traversal filenames (e.g. ../../evil.exe). The Zip Slip vulnerability can affect numerous archive formats, including zip, jar, tar, war, cpio, apk, rar and 7z. The attacker can then overwrite executable files and either invoke them remotely or wait for the system or user to call them, thus achieving remote command execution on the victim’s machine. The impact of a Zip Slip vulnerability would allow an attacker to create or overwrite existing files on the filesystem. In the context of a web application, a web shell could be placed within the application directory to achieve code execution. All users should upgrade to BCV v2.11.0 when possible to receive a patch. There are no recommended workarounds aside from upgrading.
CWE description: The product uses external input to construct a pathname that is intended to identify a file or directory that is located underneath a restricted parent directory, but the product does not properly neutralize special elements within the pathname that can cause the pathname to resolve to a location that is outside of the restricted directory.
CVSS v3 base score: 7.8
Published: 2022-01-12T19:15Z
Repository: https://github.com/Konloch/bytecode-viewer
Language: Java
Files changed: src/main/java/the/bytecode/club/bytecodeviewer/util/ZipUtils.java
Commit date: 2022-01-07 21:37:24 +0100
Commit message: Mitigate Zip Slip exlpoit


Diff: diff --git a/src/main/java/the/bytecode/club/bytecodeviewer/util/ZipUtils.java b/src/main/java/the/bytecode/club/bytecodeviewer/util/ZipUtils.java
index 499fc662..f7e9a648 100644
--- a/src/main/java/the/bytecode/club/bytecodeviewer/util/ZipUtils.java
+++ b/src/main/java/the/bytecode/club/bytecodeviewer/util/ZipUtils.java
@@ -33,10 +33,11 @@ import java.util.zip.ZipOutputStream;
 /**
  * Rudimentary utility class for Zip archives.
  */
 public final class ZipUtils {
 
+    // TODO: Maybe migrate to org.apache.commons.compress.archivers.examples.Expander?
     /**
      * Unzip files to path.
      *
      * @param jarPath        the zip file name
      * @param destinationDir the file extract path
@@ -65,10 +66,15 @@ public final class ZipUtils {
                 JarEntry entry = enums.nextElement();
 
                 String fileName = destinationDir + File.separator + entry.getName();
                 File f = new File(fileName);
 
+                if (!f.getCanonicalPath().startsWith(destinationDir)) {
+                    System.out.println("Zip Slip exploit detected. Skipping entry " + entry.getName());
+                    continue;
+                }
+
                 File parent = f.getParentFile();
                 if (!parent.exists()) {
                     parent.mkdirs();
                 }
 
@@ -104,19 +110,19 @@ public final class ZipUtils {
         }
     }
 
     public static void zipFolder(String srcFolder, String destZipFile, String ignore) throws Exception {
         try (FileOutputStream fileWriter = new FileOutputStream(destZipFile);
-             ZipOutputStream zip = new ZipOutputStream(fileWriter)){
+             ZipOutputStream zip = new ZipOutputStream(fileWriter)) {
             addFolderToZip("", srcFolder, zip, ignore);
             zip.flush();
         }
     }
 
     public static void zipFolderAPKTool(String srcFolder, String destZipFile) throws Exception {
         try (FileOutputStream fileWriter = new FileOutputStream(destZipFile);
-             ZipOutputStream zip = new ZipOutputStream(fileWriter)){
+             ZipOutputStream zip = new ZipOutputStream(fileWriter)) {
             addFolderToZipAPKTool("", srcFolder, zip);
             zip.flush();
         }
     }
 
@@ -197,6 +203,6 @@ public final class ZipUtils {
             } else {
                 addFileToZipAPKTool(path + "/" + folder.getName(), srcFolder + "/" + fileName, zip);
             }
         }
     }
-}
\ No newline at end of file
+}

Vulnerable code:              ZipOutputStream zip = new ZipOutputStream(fileWriter)){
             ZipOutputStream zip = new ZipOutputStream(fileWriter)){
}
Fixed code:     // TODO: Maybe migrate to org.apache.commons.compress.archivers.examples.Expander?
                if (!f.getCanonicalPath().startsWith(destinationDir)) {
                    System.out.println("Zip Slip exploit detected. Skipping entry " + entry.getName());
                    continue;
                }

             ZipOutputStream zip = new ZipOutputStream(fileWriter)) {
             ZipOutputStream zip = new ZipOutputStream(fileWriter)) {
}