You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@tika.apache.org by ta...@apache.org on 2017/09/22 20:48:19 UTC

[tika] branch master updated: TIKA-2470 -- modernize DocumentBuilderFactory security for Java 9

This is an automated email from the ASF dual-hosted git repository.

tallison pushed a commit to branch master
in repository https://gitbox.apache.org/repos/asf/tika.git


The following commit(s) were added to refs/heads/master by this push:
     new 0e38f94  TIKA-2470 -- modernize DocumentBuilderFactory security for Java 9
0e38f94 is described below

commit 0e38f9419121f08117283e1876e8abd02b2ab52f
Author: tballison <ta...@mitre.org>
AuthorDate: Fri Sep 22 16:48:09 2017 -0400

    TIKA-2470 -- modernize DocumentBuilderFactory security for Java 9
---
 .../java/org/apache/tika/utils/XMLReaderUtils.java | 46 ++++++++--------------
 .../test/java/org/apache/tika/TestXXEInXML.java    | 14 +++++++
 2 files changed, 31 insertions(+), 29 deletions(-)

diff --git a/tika-core/src/main/java/org/apache/tika/utils/XMLReaderUtils.java b/tika-core/src/main/java/org/apache/tika/utils/XMLReaderUtils.java
index a326f14..98fceeb 100644
--- a/tika-core/src/main/java/org/apache/tika/utils/XMLReaderUtils.java
+++ b/tika-core/src/main/java/org/apache/tika/utils/XMLReaderUtils.java
@@ -41,7 +41,8 @@ import javax.xml.transform.TransformerFactoryConfigurationError;
 
 import java.io.IOException;
 import java.io.StringReader;
-import java.lang.reflect.Method;
+import java.util.logging.Level;
+import java.util.logging.Logger;
 
 /**
  * Utility functions for reading XML.  If you are doing SAX parsing, make sure
@@ -49,6 +50,7 @@ import java.lang.reflect.Method;
  * XML External Entity attacks.
  */
 public class XMLReaderUtils {
+    private static final Logger LOG = Logger.getLogger(XMLReaderUtils.class.getName());
 
     private static final EntityResolver IGNORING_SAX_ENTITY_RESOLVER = new EntityResolver() {
         public InputSource resolveEntity(String publicId, String systemId) throws SAXException, IOException {
@@ -157,13 +159,14 @@ public class XMLReaderUtils {
      */
     public static DocumentBuilderFactory getDocumentBuilderFactory() {
         //borrowed from Apache POI
-        DocumentBuilderFactory documentBuilderFactory = DocumentBuilderFactory.newInstance();
-        documentBuilderFactory.setNamespaceAware(true);
-        documentBuilderFactory.setValidating(false);
-        tryToSetSAXFeatureOnDOMFactory(documentBuilderFactory,
-                XMLConstants.FEATURE_SECURE_PROCESSING, true);
-        tryToSetXercesManager(documentBuilderFactory);
-        return documentBuilderFactory;
+        DocumentBuilderFactory factory = DocumentBuilderFactory.newInstance();
+        factory.setExpandEntityReferences(false);
+        trySetSAXFeature(factory, XMLConstants.FEATURE_SECURE_PROCESSING, true);
+        trySetSAXFeature(factory, "http://xml.org/sax/features/external-general-entities", false);
+        trySetSAXFeature(factory, "http://xml.org/sax/features/external-parameter-entities", false);
+        trySetSAXFeature(factory, "http://apache.org/xml/features/nonvalidating/load-external-dtd", false);
+        trySetSAXFeature(factory, "http://apache.org/xml/features/nonvalidating/load-dtd-grammar", false);
+        return factory;
     }
 
     /**
@@ -208,28 +211,13 @@ public class XMLReaderUtils {
         return factory;
     }
 
-    private static void tryToSetSAXFeatureOnDOMFactory(DocumentBuilderFactory dbf, String feature, boolean value) {
+    private static void trySetSAXFeature(DocumentBuilderFactory documentBuilderFactory, String feature, boolean enabled) {
         try {
-            dbf.setFeature(feature, value);
-        } catch (Exception | AbstractMethodError e) {
-        }
-    }
-
-    private static void tryToSetXercesManager(DocumentBuilderFactory dbf) {
-        // Try built-in JVM one first, standalone if not
-        for (String securityManagerClassName : new String[]{
-                "com.sun.org.apache.xerces.internal.util.SecurityManager",
-                "org.apache.xerces.util.SecurityManager"
-        }) {
-            try {
-                Object mgr = Class.forName(securityManagerClassName).newInstance();
-                Method setLimit = mgr.getClass().getMethod("setEntityExpansionLimit", Integer.TYPE);
-                setLimit.invoke(mgr, 4096);
-                dbf.setAttribute("http://apache.org/xml/properties/security-manager", mgr);
-                // Stop once one can be setup without error
-                return;
-            } catch (Throwable t) {
-            }
+            documentBuilderFactory.setFeature(feature, enabled);
+        } catch (Exception e) {
+            LOG.log(Level.WARNING, "SAX Feature unsupported: "+feature, e);
+        } catch (AbstractMethodError ame) {
+            LOG.log(Level.WARNING, "Cannot set SAX feature because outdated XML parser in classpath: "+ feature, ame);
         }
     }
 
diff --git a/tika-parsers/src/test/java/org/apache/tika/TestXXEInXML.java b/tika-parsers/src/test/java/org/apache/tika/TestXXEInXML.java
index 28fe85c..3dd394d 100644
--- a/tika-parsers/src/test/java/org/apache/tika/TestXXEInXML.java
+++ b/tika-parsers/src/test/java/org/apache/tika/TestXXEInXML.java
@@ -1,5 +1,6 @@
 package org.apache.tika;
 
+import org.apache.tika.config.TikaConfig;
 import org.apache.tika.exception.TikaException;
 import org.apache.tika.io.IOUtils;
 import org.apache.tika.metadata.Metadata;
@@ -174,6 +175,19 @@ public class TestXXEInXML extends TikaTest {
         }
     }
 
+    @Test
+    public void testDOMTikaConfig() throws Exception {
+        //tests the DOM reader in TikaConfig
+        //if the safeguards aren't in place, this throws a FNFE
+        try (InputStream is =
+                getResourceAsStream("/org/apache/tika/config/TIKA-1558-blacklist.xml") ) {
+            ByteArrayOutputStream bos = new ByteArrayOutputStream();
+            IOUtils.copy(is, bos);
+            byte[] injected = injectXML(bos.toByteArray());
+            TikaConfig tikaConfig = new TikaConfig(new ByteArrayInputStream(injected));
+        }
+    }
+
     private Path injectZippedXMLs(Path original, boolean includeSlides) throws IOException {
         ZipFile input = new ZipFile(original.toFile());
         File output = Files.createTempFile("tika-xxe-", ".zip").toFile();

-- 
To stop receiving notification emails like this one, please contact
['"commits@tika.apache.org" <co...@tika.apache.org>'].