You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@tika.apache.org by ju...@apache.org on 2011/10/05 17:05:00 UTC

svn commit: r1179254 - in /tika/trunk/tika-core/src: main/java/org/apache/tika/sax/SecureContentHandler.java test/java/org/apache/tika/sax/SecureContentHandlerTest.java

Author: jukka
Date: Wed Oct  5 15:05:00 2011
New Revision: 1179254

URL: http://svn.apache.org/viewvc?rev=1179254&view=rev
Log:
TIKA-741: "Zip bomb" (XML nesting) detection is too strict

Add a separate check for the nesting level of <div class="package-entry"> elements produced by the ParsingEmbeddedDocumentExtractor class.

Change default settings for 100 levels of nested XML elements and 10 levels of nested package entries.

Add test cases.

Modified:
    tika/trunk/tika-core/src/main/java/org/apache/tika/sax/SecureContentHandler.java
    tika/trunk/tika-core/src/test/java/org/apache/tika/sax/SecureContentHandlerTest.java

Modified: tika/trunk/tika-core/src/main/java/org/apache/tika/sax/SecureContentHandler.java
URL: http://svn.apache.org/viewvc/tika/trunk/tika-core/src/main/java/org/apache/tika/sax/SecureContentHandler.java?rev=1179254&r1=1179253&r2=1179254&view=diff
==============================================================================
--- tika/trunk/tika-core/src/main/java/org/apache/tika/sax/SecureContentHandler.java (original)
+++ tika/trunk/tika-core/src/main/java/org/apache/tika/sax/SecureContentHandler.java Wed Oct  5 15:05:00 2011
@@ -17,6 +17,7 @@
 package org.apache.tika.sax;
 
 import java.io.IOException;
+import java.util.LinkedList;
 
 import org.apache.tika.exception.TikaException;
 import org.apache.tika.io.TikaInputStream;
@@ -54,6 +55,11 @@ public class SecureContentHandler extend
     private int currentDepth = 0;
 
     /**
+     * Current number of nested &lt;div class="package-entr"&gt; elements.
+     */
+    private LinkedList<Integer> packageEntryDepths = new LinkedList<Integer>();
+
+    /**
      * Output threshold.
      */
     private long threshold = 1000000;
@@ -66,7 +72,12 @@ public class SecureContentHandler extend
     /**
      * Maximum XML element nesting level.
      */
-    private int maxDepth = 30;
+    private int maxDepth = 100;
+
+    /**
+     * Maximum package entry nesting level.
+     */
+    private int maxPackageEntryDepth = 10;
 
     /**
      * Decorates the given content handler with zip bomb prevention based
@@ -138,6 +149,26 @@ public class SecureContentHandler extend
 
 
     /**
+     * Sets the maximum package entry nesting level. If this depth level is
+     * exceeded then an exception gets thrown.
+     *
+     * @param depth maximum package entry nesting level
+     */
+    public void setMaximumPackageEntryDepth(int depth) {
+        this.maxPackageEntryDepth = depth;
+    }
+
+    /**
+     * Returns the maximum package entry nesting level.
+     *
+     * @return maximum package entry nesting level
+     */
+    public int getMaximumPackageEntryDepth() {
+        return maxPackageEntryDepth;
+    }
+
+
+    /**
      * Sets the maximum XML element nesting level. If this depth level is
      * exceeded then an exception gets thrown.
      *
@@ -199,20 +230,37 @@ public class SecureContentHandler extend
             String uri, String localName, String name, Attributes atts)
             throws SAXException {
         currentDepth++;
-        if (currentDepth < maxDepth) {
-            super.startElement(uri, localName, name, atts);
-        } else {
+        if (currentDepth >= maxDepth) {
             throw new SecureSAXException(
                     "Suspected zip bomb: "
                     + currentDepth + " levels of XML element nesting");
         }
+
+        if ("div".equals(name)
+                && "package-entry".equals(atts.getValue("class"))) {
+            packageEntryDepths.addLast(currentDepth);
+            if (packageEntryDepths.size() >= maxPackageEntryDepth) {
+                throw new SecureSAXException(
+                        "Suspected zip bomb: "
+                        + packageEntryDepths.size()
+                        + " levels of package entry nesting");
+            }
+        }
+
+        super.startElement(uri, localName, name, atts);
     }
 
     @Override
     public void endElement(
             String uri, String localName, String name) throws SAXException {
-        currentDepth--;
         super.endElement(uri, localName, name);
+
+        if (!packageEntryDepths.isEmpty()
+                && packageEntryDepths.getLast() == currentDepth) {
+            packageEntryDepths.removeLast();
+        }
+
+        currentDepth--;
     }
 
     @Override

Modified: tika/trunk/tika-core/src/test/java/org/apache/tika/sax/SecureContentHandlerTest.java
URL: http://svn.apache.org/viewvc/tika/trunk/tika-core/src/test/java/org/apache/tika/sax/SecureContentHandlerTest.java?rev=1179254&r1=1179253&r2=1179254&view=diff
==============================================================================
--- tika/trunk/tika-core/src/test/java/org/apache/tika/sax/SecureContentHandlerTest.java (original)
+++ tika/trunk/tika-core/src/test/java/org/apache/tika/sax/SecureContentHandlerTest.java Wed Oct  5 15:05:00 2011
@@ -20,9 +20,11 @@ import java.io.IOException;
 
 import junit.framework.TestCase;
 
+import org.apache.tika.exception.TikaException;
 import org.apache.tika.io.NullInputStream;
 import org.apache.tika.io.TikaInputStream;
 import org.xml.sax.SAXException;
+import org.xml.sax.helpers.AttributesImpl;
 import org.xml.sax.helpers.DefaultHandler;
 
 /**
@@ -113,4 +115,38 @@ public class SecureContentHandlerTest ex
         }
     }
 
+    public void testNestedElements() throws SAXException {
+        for (int i = 1; i < handler.getMaximumDepth(); i++) {
+            handler.startElement("", "x", "x", new AttributesImpl());
+        }
+        try {
+            handler.startElement("", "x", "x", new AttributesImpl());
+            fail("Nested XML element limit exceeded");
+        } catch (SAXException e) {
+            try {
+                handler.throwIfCauseOf(e);
+                throw e;
+            } catch (TikaException expected) {
+            }
+        }
+    }
+
+    public void testNestedEntries() throws SAXException {
+        AttributesImpl atts = new AttributesImpl();
+        atts.addAttribute("", "class", "class", "CDATA", "package-entry");
+        for (int i = 1; i < handler.getMaximumPackageEntryDepth(); i++) {
+            handler.startElement("", "div", "div", atts);
+        }
+        try {
+            handler.startElement("", "div", "div", atts);
+            fail("Nested XML element limit exceeded");
+        } catch (SAXException e) {
+            try {
+                handler.throwIfCauseOf(e);
+                throw e;
+            } catch (TikaException expected) {
+            }
+        }
+    }
+
 }