Java Code is implemented to uncompress zip file using java.util.zip library. Sonarqube reports Security Hotspots vulnerability as prone to " Zip Bomb " security issue with message " Make sure that expanding this archive file is safe here " in the line " ZipEntry entry = zipIn.getNextEntry();
".
As a solution, trying to use Apache Commons Compress version 1.21 library which handles Zip Bomb starting from version 1.17. For testing, downloaded a Zip Bomb Vulnerable zip file from here .
But this zip file gets uncompressed without any error/exception. What is wrong with this code mentioned under heading "Implementation using Apache Commons Compress Library"?
<dependency>
<groupId>org.apache.commons</groupId>
<artifactId>commons-compress</artifactId>
<version>1.21</version>
</dependency>
Zip Bomb Vulnerable code
private void unzipNormal(String zipFilePath, String destDirectory) {
try {
File destDir = new File(destDirectory);
if(!destDir.exists()) {
destDir.mkdir();
}
try(ZipInputStream zipIn = new ZipInputStream(new FileInputStream(zipFilePath))) {
ZipEntry entry = zipIn.getNextEntry();
while(entry != null) {
String filePath = destDirectory + File.separator + entry.getName();
if(!entry.isDirectory()) {
extractFile(zipIn, filePath);
} else {
File dir = new File(filePath);
dir.mkdir();
}
zipIn.closeEntry();
entry = zipIn.getNextEntry();
}
zipIn.close();
}
} catch (Exception ex) {
ex.printStackTrace();
}
}
private static void extractFile(ZipInputStream zipIn, String filePath) throws IOException {
try(BufferedOutputStream bos = new BufferedOutputStream(new FileOutputStream(filePath))) {
byte[] bytesIn = new byte[4096];
int read = 0;
while((read = zipIn.read(bytesIn)) != -1) {
bos.write(bytesIn, 0, read);
}
bos.close();
} catch (Exception ex) {
ex.printStackTrace();
throw ex;
}
}
Implementation using Apache Commons Compress Library
private void unzip(String srcZipFile, String destFolder) throws IOException {
Path filePath = Paths.get(srcZipFile);
try(InputStream inputStream = Files.newInputStream(filePath);
ZipArchiveInputStream i = new ZipArchiveInputStream(inputStream)
) {
System.out.println("Begin..");
ArchiveEntry entry = null;
while((entry = i.getNextEntry()) != null) {
if(!i.canReadEntryData(entry)) {
System.out.println("Continue..");
continue;
}
Path path = Paths.get(destFolder, entry.getName());
File f = path.toFile();
if(entry.isDirectory()) {
if (!f.isDirectory() && !f.mkdirs()) {
throw new IOException("failed to create directory " + f);
}
} else {
File parent = f.getParentFile();
if(!parent.isDirectory() && !parent.mkdirs()) {
throw new IOException("failed to create directory " + parent);
}
try (OutputStream o = Files.newOutputStream(f.toPath())) {
IOUtils.copy(i, o);
}
}
}
} catch (Exception ex) {
ex.printStackTrace();
}
}
Able to frame the solution with answer from here . Solution uses the Apache POI utility class and hence updated Maven pom.xml with Apache POI dependency.
Maven pom.xml
<dependency>
<groupId>org.apache.poi</groupId>
<artifactId>poi-ooxml</artifactId>
<version>4.1.2</version>
</dependency>
Solution
public static void main(String[] args) throws IOException {
Main main = new Main();
String srcZipFile = "/Users/user1/Documents/ZipBomb/zbsm.zip";
String destFolder = "/Users/user1/Documents/ZipBomb/unzipApacheLARGE/";
main.handle(srcZipFile, destFolder);
}
private void handle(String srcZipFile, String destFolder) throws IOException {
ZipSecureFile zipSecureFile = new ZipSecureFile(srcZipFile);
Enumeration<? extends ZipArchiveEntry> entries = zipSecureFile.getEntries();
while (entries.hasMoreElements()) {
ZipArchiveEntry entry = entries.nextElement();
String name = entry.getName();
try {
System.out.println("current file: " + name);
try (InputStream in = zipSecureFile.getInputStream(entry)) {
Path path = Paths.get(destFolder, entry.getName());
File f = path.toFile();
if(entry.isDirectory()) {
if (!f.isDirectory() && !f.mkdirs()) {
throw new IOException("failed to create directory " + f);
}
} else {
File parent = f.getParentFile();
if(!parent.isDirectory() && !parent.mkdirs()) {
throw new IOException("failed to create directory " + parent);
}
try (OutputStream out = Files.newOutputStream(f.toPath())) {
org.apache.poi.util.IOUtils.copy(in, out);
}
}
}
} catch (Exception e) {
throw new IOException("While handling entry " + name, e);
}
System.out.print("Completed Successfully!!");
}
}
The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.