]> source.dussan.org Git - poi.git/commitdiff
* Adjust reported text when a Zip-Bomb is detected to allow to quickly see why it...
authorDominik Stadler <centic@apache.org>
Wed, 19 Aug 2015 10:57:19 +0000 (10:57 +0000)
committerDominik Stadler <centic@apache.org>
Wed, 19 Aug 2015 10:57:19 +0000 (10:57 +0000)
* Fail only with inflation ratio lower than the min, not equals, to behave as documented
* Add getters to be able to temporarily adjust the limits for unit tests
* Allow lower inflation ratio in OOXMLPrettyPrint as this is a dev-only tool

git-svn-id: https://svn.apache.org/repos/asf/poi/trunk@1696556 13f79535-47bb-0310-9956-ffa450edef68

src/ooxml/java/org/apache/poi/dev/OOXMLPrettyPrint.java
src/ooxml/java/org/apache/poi/openxml4j/util/ZipSecureFile.java
src/ooxml/testcases/org/apache/poi/openxml4j/opc/TestPackage.java

index a05af6b4d87c7ece10e5d3e1d009b6fb2758b5ac..1a7a9d6c58afeb4affe3fb2e57e39da9b96cfb5e 100644 (file)
@@ -40,6 +40,7 @@ import javax.xml.transform.dom.DOMSource;
 import javax.xml.transform.stream.StreamResult;\r
 \r
 import org.apache.poi.openxml4j.opc.internal.ZipHelper;\r
+import org.apache.poi.openxml4j.util.ZipSecureFile;\r
 import org.apache.poi.util.IOUtils;\r
 import org.w3c.dom.Document;\r
 import org.xml.sax.InputSource;\r
@@ -56,6 +57,9 @@ public class OOXMLPrettyPrint {
     private final DocumentBuilder documentBuilder;\r
 \r
     public OOXMLPrettyPrint() throws ParserConfigurationException {\r
+        // allow files with much lower inflation rate here as there is no risk of Zip Bomb attacks in this developer tool\r
+        ZipSecureFile.setMinInflateRatio(0.00001);\r
+        \r
         documentBuilder = documentBuilderFactory.newDocumentBuilder();\r
     }\r
 \r
index 60b31ee2785eec88166ebc00cbafaef3da7e42d7..5423ea4d475603450c80794aba8cb8d69ce58cb7 100644 (file)
@@ -23,7 +23,6 @@ import java.io.IOException;
 import java.io.InputStream;\r
 import java.io.PushbackInputStream;\r
 import java.lang.reflect.Field;\r
-import java.nio.charset.Charset;\r
 import java.util.zip.InflaterInputStream;\r
 import java.util.zip.ZipEntry;\r
 import java.util.zip.ZipException;\r
@@ -51,17 +50,32 @@ public class ZipSecureFile extends ZipFile {
     /**\r
      * Sets the ratio between de- and inflated bytes to detect zipbomb.\r
      * It defaults to 1% (= 0.01d), i.e. when the compression is better than\r
-     * 1% for any given read package part, the parsing will fail\r
+     * 1% for any given read package part, the parsing will fail indicating a \r
+     * Zip-Bomb.\r
      *\r
      * @param ratio the ratio between de- and inflated bytes to detect zipbomb\r
      */\r
     public static void setMinInflateRatio(double ratio) {\r
         MIN_INFLATE_RATIO = ratio;\r
     }\r
+    \r
+    /**\r
+     * Returns the current minimum compression rate that is used.\r
+     * \r
+     * See setMinInflateRatio() for details.\r
+     *\r
+     * @return The min accepted compression-ratio.  \r
+     */\r
+    public static double getMinInflateRatio() {\r
+        return MIN_INFLATE_RATIO;\r
+    }\r
 \r
     /**\r
      * Sets the maximum file size of a single zip entry. It defaults to 4GB,\r
      * i.e. the 32-bit zip format maximum.\r
+     * \r
+     * This can be used to limit memory consumption and protect against \r
+     * security vulnerabilities when documents are provided by users.\r
      *\r
      * @param maxEntrySize the max. file size of a single zip entry\r
      */\r
@@ -72,6 +86,17 @@ public class ZipSecureFile extends ZipFile {
         MAX_ENTRY_SIZE = maxEntrySize;\r
     }\r
 \r
+    /**\r
+     * Returns the current maximum allowed uncompressed file size.\r
+     * \r
+     * See setMaxEntrySize() for details.\r
+     *\r
+     * @return The max accepted uncompressed file size. \r
+     */\r
+    public static long getMaxEntrySize() {\r
+        return MAX_ENTRY_SIZE;\r
+    }\r
+\r
     public ZipSecureFile(File file, int mode) throws IOException {\r
         super(file, mode);\r
     }\r
@@ -162,9 +187,12 @@ public class ZipSecureFile extends ZipFile {
             if (counter < MAX_ENTRY_SIZE) {\r
                 if (cis == null) return;\r
                 double ratio = (double)cis.counter/(double)counter;\r
-                if (ratio > MIN_INFLATE_RATIO) return;\r
+                if (ratio >= MIN_INFLATE_RATIO) return;\r
             }\r
-            throw new IOException("Zip bomb detected! Exiting.");\r
+            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. "\r
+                    + "You can adjust these limits via setMinInflateRatio() and setMaxEntrySize() if you need to work with files which exceed these limits. "\r
+                    + "Counter: " + counter + ", cis.counter: " + (cis == null ? 0 : cis.counter) + ", ratio: " + (cis == null ? 0 : ((double)cis.counter)/counter)\r
+                    + "Limits: MIN_INFLATE_RATIO: " + MIN_INFLATE_RATIO + ", MAX_ENTRY_SIZE: " + MAX_ENTRY_SIZE);\r
         }\r
 \r
         public ZipEntry getNextEntry() throws IOException {\r
index a6955958fbfb1b4c4fafc5d7037b20bda18cfa0f..6e3b89f53e7df7ae432c85cf7383cb469e9f845a 100644 (file)
@@ -748,12 +748,12 @@ public final class TestPackage {
         if(e instanceof InvocationTargetException) {
             InvocationTargetException t = (InvocationTargetException)e;
             IOException t2 = (IOException)t.getTargetException();
-            if("Zip bomb detected! Exiting.".equals(t2.getMessage())) {
+            if(t2.getMessage().startsWith("Zip bomb detected!")) {
                 return;
             }
         }
         
-        if ("Zip bomb detected! Exiting.".equals(e.getMessage())) {
+        if(e.getMessage().startsWith("Zip bomb detected!")) {
             return;
         }
         
@@ -766,3 +766,4 @@ public final class TestPackage {
         throw new IllegalStateException("Expected to catch an Exception because of a detected Zip Bomb, but did not find the related error message in the exception", e);        
     }
 }
+