From 2afe97762259bd86d8209b77155beda8235e3e85 Mon Sep 17 00:00:00 2001 From: Dominik Stadler Date: Sat, 17 Oct 2015 14:40:36 +0000 Subject: Bug 58499: Don't report Zip-Bomb for small files which should not cause memory issues anyway Also make error message a bit more specific and list classname in Zip-Bomb-Error to make it easier for users what the problem is and how to find out where the static methods are git-svn-id: https://svn.apache.org/repos/asf/poi/trunk@1709180 13f79535-47bb-0310-9956-ffa450edef68 --- .../apache/poi/openxml4j/util/ZipSecureFile.java | 38 ++++++++++++++++++---- 1 file changed, 31 insertions(+), 7 deletions(-) (limited to 'src/ooxml/java') diff --git a/src/ooxml/java/org/apache/poi/openxml4j/util/ZipSecureFile.java b/src/ooxml/java/org/apache/poi/openxml4j/util/ZipSecureFile.java index 5423ea4d47..b06ddcb25a 100644 --- a/src/ooxml/java/org/apache/poi/openxml4j/util/ZipSecureFile.java +++ b/src/ooxml/java/org/apache/poi/openxml4j/util/ZipSecureFile.java @@ -46,6 +46,9 @@ public class ZipSecureFile extends ZipFile { private static double MIN_INFLATE_RATIO = 0.01d; private static long MAX_ENTRY_SIZE = 0xFFFFFFFFl; + + // don't alert for expanded sizes smaller than 100k + private static long GRACE_ENTRY_SIZE = 100*1024; /** * Sets the ratio between de- and inflated bytes to detect zipbomb. @@ -183,16 +186,37 @@ public class ZipSecureFile extends ZipFile { public void advance(int advance) throws IOException { counter += advance; + // check the file size first, in case we are working on uncompressed streams - if (counter < MAX_ENTRY_SIZE) { - if (cis == null) return; - double ratio = (double)cis.counter/(double)counter; - if (ratio >= MIN_INFLATE_RATIO) return; + if(counter > MAX_ENTRY_SIZE) { + throw new IOException("Zip bomb detected! The file would exceed the max size of the expanded data in the zip-file. " + + "This may indicates that the file is used to inflate memory usage and thus could pose a security risk. " + + "You can adjust this limit via ZipSecureFile.setMaxEntrySize() if you need to work with files which are very large. " + + "Counter: " + counter + ", cis.counter: " + (cis == null ? 0 : cis.counter) + + "Limits: MAX_ENTRY_SIZE: " + MAX_ENTRY_SIZE); + } + + // no expanded size? + if (cis == null) { + return; + } + + // don't alert for small expanded size + if (counter <= GRACE_ENTRY_SIZE) { + return; } - throw new IOException("Zip bomb detected! The file would exceed certain limits which usually indicate that the file is used to inflate memory usage and thus could pose a security risk. " - + "You can adjust these limits via setMinInflateRatio() and setMaxEntrySize() if you need to work with files which exceed these limits. " + + double ratio = (double)cis.counter/(double)counter; + if (ratio >= MIN_INFLATE_RATIO) { + return; + } + + // one of the limits was reached, report it + throw new IOException("Zip bomb detected! The file would exceed the max. ratio of compressed file size to the size of the expanded data. " + + "This may indicate that the file is used to inflate memory usage and thus could pose a security risk. " + + "You can adjust this limit via ZipSecureFile.setMinInflateRatio() if you need to work with files which exceed this limit. " + "Counter: " + counter + ", cis.counter: " + (cis == null ? 0 : cis.counter) + ", ratio: " + (cis == null ? 0 : ((double)cis.counter)/counter) - + "Limits: MIN_INFLATE_RATIO: " + MIN_INFLATE_RATIO + ", MAX_ENTRY_SIZE: " + MAX_ENTRY_SIZE); + + "Limits: MIN_INFLATE_RATIO: " + MIN_INFLATE_RATIO); } public ZipEntry getNextEntry() throws IOException { -- cgit v1.2.3