Browse Source

use safe unzip to avoid zip bombs

tags/2.0.1
Jonathan Cobb 5 years ago
parent
commit
d7ebbd7a8c
3 changed files with 24 additions and 12 deletions
  1. +7
    -0
      pom.xml
  2. +16
    -11
      src/main/java/org/cobbzilla/util/io/Decompressors.java
  3. +1
    -1
      src/main/java/org/cobbzilla/util/system/OneWayFlag.java

+ 7
- 0
pom.xml View File

@@ -139,6 +139,13 @@ cobbzilla-utils is available under the Apache License, version 2: http://www.apa
<version>1.7</version> <version>1.7</version>
</dependency> </dependency>


<!-- https://mvnrepository.com/artifact/org.apache.poi/poi-ooxml -->
<dependency>
<groupId>org.apache.poi</groupId>
<artifactId>poi-ooxml</artifactId>
<version>4.1.1</version>
</dependency>

<dependency> <dependency>
<groupId>org.apache.ant</groupId> <groupId>org.apache.ant</groupId>
<artifactId>ant</artifactId> <artifactId>ant</artifactId>


+ 16
- 11
src/main/java/org/cobbzilla/util/io/Decompressors.java View File

@@ -1,10 +1,14 @@
package org.cobbzilla.util.io; package org.cobbzilla.util.io;


import lombok.Cleanup; import lombok.Cleanup;
import org.apache.commons.compress.archivers.zip.ZipArchiveEntry;
import org.apache.poi.openxml4j.util.ZipSecureFile;


import java.io.*;
import java.util.zip.ZipEntry;
import java.util.zip.ZipInputStream;
import java.io.File;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.util.Enumeration;


import static org.cobbzilla.util.daemon.ZillaRuntime.die; import static org.cobbzilla.util.daemon.ZillaRuntime.die;
import static org.cobbzilla.util.io.FileUtil.abs; import static org.cobbzilla.util.io.FileUtil.abs;
@@ -35,7 +39,7 @@ public class Decompressors {
return isTarball(name) || isZipFile(name); return isTarball(name) || isZipFile(name);
} }


private static void extractFile(ZipInputStream in, File outdir, String name) throws IOException {
private static void extractFile(InputStream in, File outdir, String name) throws IOException {
@Cleanup final FileOutputStream out = new FileOutputStream(new File(outdir, name)); @Cleanup final FileOutputStream out = new FileOutputStream(new File(outdir, name));
StreamUtil.copyLarge(in, out); StreamUtil.copyLarge(in, out);
} }
@@ -52,15 +56,16 @@ public class Decompressors {


/*** /***
* Extract zipfile to outdir with complete directory structure * Extract zipfile to outdir with complete directory structure
* Uses ZipSecureFile to avoid zip-bombs
* @param zipfile Input .zip file * @param zipfile Input .zip file
* @param outdir Output directory * @param outdir Output directory
*/ */
public static void extract(File zipfile, File outdir) throws IOException { public static void extract(File zipfile, File outdir) throws IOException {
@Cleanup final ZipInputStream zin = new ZipInputStream(new FileInputStream(zipfile));
ZipEntry entry;
String name, dir;
while ((entry = zin.getNextEntry()) != null) {
name = entry.getName();
@Cleanup final ZipSecureFile zip = new ZipSecureFile(zipfile);
final Enumeration<ZipArchiveEntry> entries = zip.getEntriesInPhysicalOrder();
while (entries.hasMoreElements()) {
final ZipArchiveEntry entry = entries.nextElement();
final String name = entry.getName();
if (entry.isDirectory()) { if (entry.isDirectory()) {
mkdirs(outdir,name); mkdirs(outdir,name);
continue; continue;
@@ -71,10 +76,10 @@ public class Decompressors {
* /foo/foo.txt * /foo/foo.txt
* /foo/ * /foo/
*/ */
dir = dirpart(name);
final String dir = dirpart(name);
if (dir != null) mkdirs(outdir,dir); if (dir != null) mkdirs(outdir,dir);


extractFile(zin, outdir, name);
extractFile(zip.getInputStream(entry), outdir, name);
} }
} }
} }

+ 1
- 1
src/main/java/org/cobbzilla/util/system/OneWayFlag.java View File

@@ -31,7 +31,7 @@ public class OneWayFlag extends AtomicBoolean {


public boolean check () { public boolean check () {
if (get()) return true; if (get()) return true;
final Boolean ok;
final boolean ok;
try { try {
ok = check.call(); ok = check.call();
} catch (Exception e) { } catch (Exception e) {


Loading…
Cancel
Save