File names of the entries in a zip archive should be considered untrusted, tainted and should be validated before being used for file system
operations. Indeed, file names can contain specially crafted values, such as '../', that change the initial path and, when accessed, resolve to a path
on the filesystem where the user should normally not have access.
A successful attack might give an attacker the ability to read, modify, or delete sensitive information from the file system and sometimes even
execute arbitrary operating system commands. This special case of path injection vulnerabilities is called "zip slip".
The mitigation strategy should be based on the whitelisting of allowed paths or characters.
Noncompliant Code Example
public static List<String> zipSlipNoncompliant(ZipFile zipFile) throws IOException {
Enumeration<? extends ZipEntry> entries = zipFile.entries();
List<String> filesContent = new ArrayList<>();
while (entries.hasMoreElements()) {
ZipEntry entry = entries.nextElement();
File file = new File(entry.getName());
String content = FileUtils.readFileToString(file, StandardCharsets.UTF_8); // Noncompliant
filesContent.add(content);
}
return filesContent;
}
Compliant Solution
public static List<String> zipSlipCompliant(ZipFile zipFile, String targetDirectory) throws IOException {
Enumeration<? extends ZipEntry> entries = zipFile.entries();
List<String> filesContent = new ArrayList<>();
while (entries.hasMoreElements()) {
ZipEntry entry = entries.nextElement();
File file = new File(entry.getName());
String canonicalDestinationPath = file.getCanonicalPath();
if (!canonicalDestinationPath.startsWith(targetDirectory)) {
throw new IOException("Entry is outside of the target directory");
}
String content = FileUtils.readFileToString(file, StandardCharsets.UTF_8); // OK
filesContent.add(content);
}
return filesContent;
}
See