VYPR
Moderate severityNVD Advisory· Published Jul 25, 2018· Updated Sep 16, 2024

CVE-2018-1002201

CVE-2018-1002201

Description

zt-zip before 1.13 is vulnerable to Zip-Slip directory traversal, allowing attackers to write arbitrary files via a malicious archive entry.

AI Insight

LLM-synthesized narrative grounded in this CVE's description and references.

zt-zip before 1.13 is vulnerable to Zip-Slip directory traversal, allowing attackers to write arbitrary files via a malicious archive entry.

Vulnerability

zt-zip versions before 1.13 are vulnerable to a directory traversal issue known as Zip-Slip [1][2]. The vulnerability occurs during archive extraction when the library does not properly validate file paths in ZipEntry names that contain ../ sequences. This allows a crafted archive with entries such as ../../evil.sh to write files outside the intended extraction directory [2][4]. The affected code path is triggered by methods that extract zip entries using the library's process or similar functions, and the vulnerability is present across multiple ecosystems, especially Java [2][4].

Exploitation

An attacker needs to provide a specially crafted zip (or other archive format) file containing entries with directory traversal patterns (e.g., ../../evil.sh) to an application that uses the zt-zip library to extract archives [2][4]. No special authentication or network position is required if the attacker can supply the archive file via user upload, email attachment, or similar vector [4]. The extraction code must use the vulnerable zt-zip version and the process method that concatenates the entry name directly with the output directory without sanitization [3]. The attacker's intended file path will be resolved outside the extraction target directory, allowing arbitrary file write.

Impact

Successful exploitation allows an attacker to write arbitrary files to the file system [1][2]. This can lead to overwriting executable files, configuration files, or other sensitive resources, potentially resulting in remote code execution if the attacker can place a malicious script or binary that is later executed [4]. The impact is significant on both client machines and servers, as the attacker may gain file system access beyond the extraction output directory [2][4].

Mitigation

The vulnerability was fixed in zt-zip version 1.13, released in 2018 [1][2][3]; users should upgrade to that version or later. The fix, visible in commit 759b72f [3], adds path validation: during extraction, the library checks if the canonical path of the output file starts with the canonical path of the target directory, and throws a ZipException if traversal is detected [3]. If immediate upgrade is not possible, applications should validate or sanitize all archive entry paths before extraction. No workaround is provided by the library, and the vulnerability is not listed on CISA's Known Exploited Vulnerabilities (KEV) catalog as of writing.

AI Insight generated on May 22, 2026. Synthesized from this CVE's description and the cited reference URLs; citations are validated against the source bundle.

Affected packages

Versions sourced from the GitHub Security Advisory.

PackageAffected versionsPatched versions
org.zeroturnaround:zt-zipMaven
< 1.131.13

Affected products

2

Patches

1
759b72f33bc8

Fixed potential security vulnerability reported by Snyk Security Research Team

https://github.com/zeroturnaround/zt-zipToomas RomerApr 26, 2018via ghsa
4 files changed · +97 0
  • src/main/java/org/zeroturnaround/zip/ZipUtil.java+36 0 modified
    @@ -1150,6 +1150,15 @@ public void process(InputStream in, ZipEntry zipEntry) throws IOException {
           String name = mapper.map(zipEntry.getName());
           if (name != null) {
             File file = new File(outputDir, name);
    +
    +        /* If we see the relative traversal string of ".." we need to make sure
    +         * that the outputdir + name doesn't leave the outputdir. See
    +         * DirectoryTraversalMaliciousTest for details.
    +         */
    +        if (name.indexOf("..") != -1 && !file.getCanonicalPath().startsWith(outputDir.getCanonicalPath())) {
    +          throw new ZipException("The file "+name+" is trying to leave the target output directory of "+outputDir+". Ignoring this file.");
    +        }
    +
             if (zipEntry.isDirectory()) {
               FileUtils.forceMkdir(file);
             }
    @@ -1218,11 +1227,29 @@ public void process(InputStream in, ZipEntry zipEntry) throws IOException {
                 parentDirectory = file;
               }
               File destFile = new File(parentDirectory, dirs[dirs.length - 1]);
    +
    +          /* If we see the relative traversal string of ".." we need to make sure
    +           * that the outputdir + name doesn't leave the outputdir. See
    +           * DirectoryTraversalMaliciousTest for details.
    +           */
    +          if (name.indexOf("..") != -1 && !destFile.getCanonicalPath().startsWith(outputDir.getCanonicalPath())) {
    +            throw new ZipException("The file "+name+" is trying to leave the target output directory of "+outputDir+". Ignoring this file.");
    +          }
    +
               FileUtils.copy(in, destFile);
             }
             // it could be that there are just top level files that the unpacker is used for
             else {
               File destFile = new File(outputDir, name);
    +
    +          /* If we see the relative traversal string of ".." we need to make sure
    +           * that the outputdir + name doesn't leave the outputdir. See
    +           * DirectoryTraversalMaliciousTest for details.
    +           */
    +          if (name.indexOf("..") != -1 && !destFile.getCanonicalPath().startsWith(outputDir.getCanonicalPath())) {
    +            throw new ZipException("The file "+name+" is trying to leave the target output directory of "+outputDir+". Ignoring this file.");
    +          }
    +
               FileUtils.copy(in, destFile);
             }
           }
    @@ -1258,6 +1285,15 @@ else if (!rootDir.equals(root)) {
           String name = mapper.map(getUnrootedName(root, zipEntry.getName()));
           if (name != null) {
             File file = new File(outputDir, name);
    +
    +        /* If we see the relative traversal string of ".." we need to make sure
    +         * that the outputdir + name doesn't leave the outputdir. See
    +         * DirectoryTraversalMaliciousTest for details.
    +         */
    +        if (name.indexOf("..") != -1 && !file.getCanonicalPath().startsWith(outputDir.getCanonicalPath())) {
    +          throw new ZipException("The file "+name+" is trying to leave the target output directory of "+outputDir+". Ignoring this file.");
    +        }
    +
             if (zipEntry.isDirectory()) {
               FileUtils.forceMkdir(file);
             }
    
  • src/test/java/org/zeroturnaround/zip/DirectoryTraversalMaliciousTest.java+61 0 added
    @@ -0,0 +1,61 @@
    +package org.zeroturnaround.zip;
    +
    +/**
    + *    Copyright (C) 2012 ZeroTurnaround LLC <support@zeroturnaround.com>
    + *
    + *    Licensed under the Apache License, Version 2.0 (the "License");
    + *    you may not use this file except in compliance with the License.
    + *    You may obtain a copy of the License at
    + *
    + *        http://www.apache.org/licenses/LICENSE-2.0
    + *
    + *    Unless required by applicable law or agreed to in writing, software
    + *    distributed under the License is distributed on an "AS IS" BASIS,
    + *    WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
    + *    See the License for the specific language governing permissions and
    + *    limitations under the License.
    + */
    +import java.io.File;
    +
    +import junit.framework.TestCase;
    +
    +public class DirectoryTraversalMaliciousTest extends TestCase {
    +  /*
    +   * This is the contents of the file. There is one evil file that tries to get out of the
    +   * target.
    +   *
    +   * $ unzip -t zip-slip.zip
    +   * Archive: zip-slip.zip
    +   * testing: good.txt OK
    +   * testing: ../../../../../../../../../../../../../../../../../../../../../../../../../../../../../../../../../../../../../../../../tmp/evil.txt OK
    +   * No errors detected in compressed data of zip-slip.zip.
    +   */
    +  private static final File badFile = new File("src/test/resources/zip-malicious-traversal.zip");
    +  private static final File badFileBackslashes = new File("src/test/resources/zip-malicious-traversal-backslashes.zip");
    +
    +  public void testUnpackDoesntLeaveTarget() throws Exception {
    +    File file = File.createTempFile("temp", null);
    +    File tmpDir = file.getParentFile();
    +
    +    try {
    +      ZipUtil.unpack(badFile, tmpDir);
    +      fail();
    +    }
    +    catch (ZipException e) {
    +      assertTrue(true);
    +    }
    +  }
    +
    +  public void testUnwrapDoesntLeaveTarget() throws Exception {
    +    File file = File.createTempFile("temp", null);
    +    File tmpDir = file.getParentFile();
    +
    +    try {
    +      ZipUtil.iterate(badFileBackslashes, new ZipUtil.BackslashUnpacker(tmpDir));
    +      fail();
    +    }
    +    catch (ZipException e) {
    +      assertTrue(true);
    +    }
    +  }
    +}
    
  • src/test/resources/zip-malicious-traversal-backslashes.zip+0 0 added
  • src/test/resources/zip-malicious-traversal.zip+0 0 added

Vulnerability mechanics

Generated on May 9, 2026. Inputs: CWE entries + fix-commit diffs from this CVE's patches. Citations validated against bundle.

References

6

News mentions

0

No linked articles in our index yet.