CVE-2010-3260: Permissions, Privileges, and Access Controls (CWE-264)
value: oxf/xml/xerces/XercesSAXParserFactoryImpl.java in the xforms-server component in the XForms service in Orbeon Forms before 3.9 does not properly restrict DTDs in Ajax requests, which allows remote attackers to read arbitrary files or send HTTP requests to intranet servers via an entity declaration in conjunction with an entity reference, related to an "XML injection" issue.
CWE description: Weaknesses in this category are related to the management of permissions, privileges, and other security features that are used to perform access control.
Published: 2011-04-27T00:55Z
Repository: https://github.com/orbeon/orbeon-forms
Language: Java
Files changed: src/java/org/orbeon/oxf/xml/xerces/XercesSAXParserFactoryImpl.java
Commit date: 2010-12-03 16:35:02 -0800
Commit message: Implemented "[ #315668 ] Disable loading of external entities in XML parsing by default".

Diff: diff --git a/src/java/org/orbeon/oxf/xml/xerces/XercesSAXParserFactoryImpl.java b/src/java/org/orbeon/oxf/xml/xerces/XercesSAXParserFactoryImpl.java
index c4c59e48b..fc0d716f4 100644
--- a/src/java/org/orbeon/oxf/xml/xerces/XercesSAXParserFactoryImpl.java
+++ b/src/java/org/orbeon/oxf/xml/xerces/XercesSAXParserFactoryImpl.java
@@ -2,17 +2,13 @@ package org.orbeon.oxf.xml.xerces;
 
 import org.orbeon.oxf.common.OXFException;
 import org.xml.sax.SAXException;
 import org.xml.sax.SAXNotRecognizedException;
 
-import javax.xml.parsers.ParserConfigurationException;
 import javax.xml.parsers.SAXParser;
 import javax.xml.parsers.SAXParserFactory;
-import java.util.Collection;
-import java.util.Collections;
-import java.util.Hashtable;
-import java.util.Map;
+import java.util.*;
 
 /**
  * Boasts a couple of improvements over the 'stock' xerces parser factory.
  *
  * o Doesn't create a new parser every time one calls setFeature or getFeature.  Stock one
@@ -40,51 +36,47 @@ public class XercesSAXParserFactoryImpl extends SAXParserFactory {
     private static final Map defaultFeaturesValidatingNoXInclude;
 
     static {
         {
             final OrbeonParserConfiguration configuration = XercesSAXParser.makeConfig(false, true);
-            final Collection features = configuration.getRecognizedFeatures();
-            recognizedFeaturesNonValidatingXInclude = Collections.unmodifiableCollection(features);
+            final Collection recognizedFeatures = configuration.getRecognizedFeatures();
+            recognizedFeaturesNonValidatingXInclude = Collections.unmodifiableCollection(recognizedFeatures);
             defaultFeaturesNonValidatingXInclude = configuration.getFeatures();
-            // This was being done in XMLUtils.createSaxParserFactory before.  Maybe want to
-            // move it back if we decide to make this class more general purpose.
-            defaultFeaturesNonValidatingXInclude.put("http://xml.org/sax/features/namespaces", Boolean.TRUE);
-            defaultFeaturesNonValidatingXInclude.put("http://xml.org/sax/features/namespace-prefixes", Boolean.FALSE);
+            addDefaultFeatures(defaultFeaturesNonValidatingXInclude);
         }
         {
             final OrbeonParserConfiguration configuration = XercesSAXParser.makeConfig(false, false);
             final Collection features = configuration.getRecognizedFeatures();
             recognizedFeaturesNonValidatingNoXInclude = Collections.unmodifiableCollection(features);
             defaultFeaturesNonValidatingNoXInclude = configuration.getFeatures();
-            // This was being done in XMLUtils.createSaxParserFactory before.  Maybe want to
-            // move it back if we decide to make this class more general purpose.
-            defaultFeaturesNonValidatingNoXInclude.put("http://xml.org/sax/features/namespaces", Boolean.TRUE);
-            defaultFeaturesNonValidatingNoXInclude.put("http://xml.org/sax/features/namespace-prefixes", Boolean.FALSE);
+            addDefaultFeatures(defaultFeaturesNonValidatingNoXInclude);
         }
 
         {
             final OrbeonParserConfiguration configuration = XercesSAXParser.makeConfig(true, true);
             final Collection features = configuration.getRecognizedFeatures();
             recognizedFeaturesValidatingXInclude = Collections.unmodifiableCollection(features);
             defaultFeaturesValidatingXInclude = configuration.getFeatures();
-            // This was being done in XMLUtils.createSaxParserFactory before.  Maybe want to
-            // move it back if we decide to make this class more general purpose.
-            defaultFeaturesValidatingXInclude.put("http://xml.org/sax/features/namespaces", Boolean.TRUE);
-            defaultFeaturesValidatingXInclude.put("http://xml.org/sax/features/namespace-prefixes", Boolean.FALSE);
+            addDefaultFeatures(defaultFeaturesValidatingXInclude);
         }
         {
             final OrbeonParserConfiguration configuration = XercesSAXParser.makeConfig(true, false);
             final Collection features = configuration.getRecognizedFeatures();
             recognizedFeaturesValidatingNoXInclude = Collections.unmodifiableCollection(features);
             defaultFeaturesValidatingNoXInclude = configuration.getFeatures();
-            // This was being done in XMLUtils.createSaxParserFactory before.  Maybe want to
-            // move it back if we decide to make this class more general purpose.
-            defaultFeaturesValidatingNoXInclude.put("http://xml.org/sax/features/namespaces", Boolean.TRUE);
-            defaultFeaturesValidatingNoXInclude.put("http://xml.org/sax/features/namespace-prefixes", Boolean.FALSE);
+            addDefaultFeatures(defaultFeaturesValidatingNoXInclude);
         }
     }
 
+    private static void addDefaultFeatures(Map features) {
+        features.put("http://xml.org/sax/features/namespaces", Boolean.TRUE);
+        features.put("http://xml.org/sax/features/namespace-prefixes", Boolean.FALSE);
+        // For security purposes, disable external entities
+        features.put("http://xml.org/sax/features/external-general-entities", Boolean.FALSE);
+        features.put("http://xml.org/sax/features/external-parameter-entities", Boolean.FALSE);
+    }
+
     private final Hashtable features;
     private final boolean validating;
     private final boolean handleXInclude;
 
     public XercesSAXParserFactoryImpl() {
@@ -110,18 +102,17 @@ public class XercesSAXParserFactoryImpl extends SAXParserFactory {
     public void setFeature(final String key, final boolean val) throws SAXNotRecognizedException {
         if (!getRecognizedFeatures().contains(key)) throw new SAXNotRecognizedException(key);
         features.put(key, val ? Boolean.TRUE : Boolean.FALSE);
     }
 
-    public SAXParser newSAXParser() throws ParserConfigurationException {
+    public SAXParser newSAXParser() {
         final SAXParser ret;
         try {
             ret = new XercesJAXPSAXParser(this, features, validating, handleXInclude);
         } catch (final SAXException se) {
             // Translate to ParserConfigurationException
             throw new OXFException(se); // so we see a decent stack trace!
-//            throw new ParserConfigurationException(se.getMessage());
         }
         return ret;
     }
 
     private Collection getRecognizedFeatures() {

Vulnerable code: import javax.xml.parsers.ParserConfigurationException;
import java.util.Collection;
import java.util.Collections;
import java.util.Hashtable;
import java.util.Map;
            final Collection features = configuration.getRecognizedFeatures();
            recognizedFeaturesNonValidatingXInclude = Collections.unmodifiableCollection(features);
            // This was being done in XMLUtils.createSaxParserFactory before.  Maybe want to
            // move it back if we decide to make this class more general purpose.
            defaultFeaturesNonValidatingXInclude.put("http://xml.org/sax/features/namespaces", Boolean.TRUE);
            defaultFeaturesNonValidatingXInclude.put("http://xml.org/sax/features/namespace-prefixes", Boolean.FALSE);
            // This was being done in XMLUtils.createSaxParserFactory before.  Maybe want to
            // move it back if we decide to make this class more general purpose.
            defaultFeaturesNonValidatingNoXInclude.put("http://xml.org/sax/features/namespaces", Boolean.TRUE);
            defaultFeaturesNonValidatingNoXInclude.put("http://xml.org/sax/features/namespace-prefixes", Boolean.FALSE);
            // This was being done in XMLUtils.createSaxParserFactory before.  Maybe want to
            // move it back if we decide to make this class more general purpose.
            defaultFeaturesValidatingXInclude.put("http://xml.org/sax/features/namespaces", Boolean.TRUE);
            defaultFeaturesValidatingXInclude.put("http://xml.org/sax/features/namespace-prefixes", Boolean.FALSE);
            // This was being done in XMLUtils.createSaxParserFactory before.  Maybe want to
            // move it back if we decide to make this class more general purpose.
            defaultFeaturesValidatingNoXInclude.put("http://xml.org/sax/features/namespaces", Boolean.TRUE);
            defaultFeaturesValidatingNoXInclude.put("http://xml.org/sax/features/namespace-prefixes", Boolean.FALSE);
    public SAXParser newSAXParser() throws ParserConfigurationException {
//            throw new ParserConfigurationException(se.getMessage());
Fixed code: import java.util.*;
            final Collection recognizedFeatures = configuration.getRecognizedFeatures();
            recognizedFeaturesNonValidatingXInclude = Collections.unmodifiableCollection(recognizedFeatures);
            addDefaultFeatures(defaultFeaturesNonValidatingXInclude);
            addDefaultFeatures(defaultFeaturesNonValidatingNoXInclude);
            addDefaultFeatures(defaultFeaturesValidatingXInclude);
            addDefaultFeatures(defaultFeaturesValidatingNoXInclude);
    private static void addDefaultFeatures(Map features) {
        features.put("http://xml.org/sax/features/namespaces", Boolean.TRUE);
        features.put("http://xml.org/sax/features/namespace-prefixes", Boolean.FALSE);
        // For security purposes, disable external entities
        features.put("http://xml.org/sax/features/external-general-entities", Boolean.FALSE);
        features.put("http://xml.org/sax/features/external-parameter-entities", Boolean.FALSE);
    }

    public SAXParser newSAXParser() {