Unzip File Folder Example in Java (2024)
In this tutorial, will learn how to Unzip the folder using Core Java libraries. To unzip a zip file, we will make use of ZipInputStream to read the zip file.
While unzip the zip, added validation to prevent the zip slip vulnerability using normalize method.
What is zip slip vulnerability?
Zip Slip is a type of Directory Traversal which can be used to remove files from an archive. The Directory Traversal vulnerability is based primarily on the ability of an attacker to gain access to parts of the file system outside the target folder they should reside in.
What does it mean by normalizing the Path?
Normalizing a path involves changing the string that identifies a path or file, so that it conforms to a valid path on the target operating system.
// Check for zip slip attack
public static Path zipSlipVulnerabilityProtect(ZipEntry zipEntry, Path targetDir)
throws IOException {
/**
* resolve(String other) method of java. nio. file.Path used to converts a given
* path string to a Path and resolves it against this Path in the exact same manner
* as specified by the resolve method
*/
Path dirResolved = targetDir.resolve(zipEntry.getName());
/**
* Normalizing a path involves modifying the string that identifies a
* path or file so that it conforms to a valid path on the target operating system.
*/
//normalize the path on target directory or else throw exception
Path normalizePath = dirResolved.normalize();
if (!normalizePath.startsWith(targetDir)) {
throw new IOException("Invalid zip: " + zipEntry.getName());
}
return normalizePath;
}
Below example will unzip a zip file from sourcePath to targetPath.
package com.techgeeknext;
import java.io.File;
import java.io.FileInputStream;
import java.io.IOException;
import java.nio.file.Files;
import java.nio.file.Path;
import java.nio.file.Paths;
import java.nio.file.StandardCopyOption;
import java.util.zip.ZipEntry;
import java.util.zip.ZipInputStream;
public class UnzipUtility {
public static void main(String[] args) {
Path sourcePath = Paths.get("D:\\Notes.zip");
Path targetPath = Paths.get("D:\\Notes");
try {
unzipFolder(sourcePath, targetPath);
System.out.println("Unzipped successfully at location : "+targetPath);
} catch (IOException e) {
e.printStackTrace();
}
}
public static void unzipFolder(Path sourceFolder, Path targetFolder) throws IOException {
try (ZipInputStream zipInputStream = new ZipInputStream(new FileInputStream(sourceFolder.toFile()))) {
// list files in zip
ZipEntry zipEntry = zipInputStream.getNextEntry();
while (zipEntry != null) {
// Check for zip slip vulnerability attack
Path newUnzipPath = zipSlipVulnerabilityProtect(zipEntry, targetFolder);
boolean isDirectory = false;
//check for files or directory
if (zipEntry.getName().endsWith(File.separator)) {
isDirectory = true;
}
if (isDirectory) {
Files.createDirectories(newUnzipPath);
} else {
if (newUnzipPath.getParent() != null) {
if (Files.notExists(newUnzipPath.getParent())) {
Files.createDirectories(newUnzipPath.getParent());
}
}
// copy files using nio
Files.copy(zipInputStream, newUnzipPath, StandardCopyOption.REPLACE_EXISTING);
}
zipEntry = zipInputStream.getNextEntry();
}
zipInputStream.closeEntry();
}
}
// Check for zip slip attack
public static Path zipSlipVulnerabilityProtect(ZipEntry zipEntry, Path targetDir)
throws IOException {
/**
* resolve(String other) method of java. nio. file.Path used to converts a given
* path string to a Path and resolves it against this Path in the exact same manner
* as specified by the resolve method
*/
Path dirResolved = targetDir.resolve(zipEntry.getName());
/**
* Normalizing a path involves modifying the string that identifies a
* path or file so that it conforms to a valid path on the target operating system.
*/
//normalize the path on target directory or else throw exception
Path normalizePath = dirResolved.normalize();
if (!normalizePath.startsWith(targetDir)) {
throw new IOException("Invalid zip: " + zipEntry.getName());
}
return normalizePath;
}
}
Output:
Unzipped successfully at location : D:\Notes