diff --git a/pom.xml b/pom.xml index 7d5d90798..63bac1261 100644 --- a/pom.xml +++ b/pom.xml @@ -149,6 +149,11 @@ + + org.apache.commons + commons-secure-xml + 1.0.0 + javax.servlet servlet-api diff --git a/src/changes/changes.xml b/src/changes/changes.xml index cc310276b..32630e06e 100644 --- a/src/changes/changes.xml +++ b/src/changes/changes.xml @@ -49,6 +49,7 @@ The type attribute can be add,update,fix,remove. + Create the DOM and JDOM parsers and the XML transformer through org.apache.commons:commons-secure-xml, so external entities and DTDs are no longer fetched by default. POM assembly:single does not generate binary convenience files (tar/zip). Make dynamicPropertyHandlerMap in ValueUtils thread-safe #251. Refactor JXPathIntrospector internal static maps to use concurrent classes instead of synchronization. diff --git a/src/main/java/org/apache/commons/jxpath/XMLDocumentContainer.java b/src/main/java/org/apache/commons/jxpath/XMLDocumentContainer.java index cb09f657b..c8001586a 100644 --- a/src/main/java/org/apache/commons/jxpath/XMLDocumentContainer.java +++ b/src/main/java/org/apache/commons/jxpath/XMLDocumentContainer.java @@ -22,10 +22,10 @@ import javax.xml.transform.Source; import javax.xml.transform.Transformer; -import javax.xml.transform.TransformerFactory; import javax.xml.transform.dom.DOMResult; import org.apache.commons.jxpath.xml.DocumentContainer; +import org.apache.commons.xml.secure.SecureTransformerFactory; /** * An XML document container reads and parses XML only when it is accessed. JXPath traverses Containers transparently - you use the same paths to access objects @@ -85,7 +85,7 @@ public Object getValue() { try { if (source != null) { final DOMResult result = new DOMResult(); - final Transformer trans = TransformerFactory.newInstance().newTransformer(); + final Transformer trans = SecureTransformerFactory.newInstance().newTransformer(); trans.transform(source, result); document = result.getNode(); } else { diff --git a/src/main/java/org/apache/commons/jxpath/xml/DOMParser.java b/src/main/java/org/apache/commons/jxpath/xml/DOMParser.java index 26e7c69d7..35796d5be 100644 --- a/src/main/java/org/apache/commons/jxpath/xml/DOMParser.java +++ b/src/main/java/org/apache/commons/jxpath/xml/DOMParser.java @@ -22,6 +22,7 @@ import javax.xml.parsers.DocumentBuilderFactory; import org.apache.commons.jxpath.JXPathException; +import org.apache.commons.xml.secure.SecureDocumentBuilderFactory; /** * An implementation of the XMLParser interface that produces a DOM Document. @@ -38,7 +39,7 @@ public DOMParser() { @Override public Object parseXML(final InputStream stream) { try { - final DocumentBuilderFactory factory = DocumentBuilderFactory.newInstance(); + final DocumentBuilderFactory factory = SecureDocumentBuilderFactory.newInstance(); factory.setValidating(isValidating()); factory.setNamespaceAware(isNamespaceAware()); factory.setIgnoringElementContentWhitespace(isIgnoringElementContentWhitespace()); diff --git a/src/main/java/org/apache/commons/jxpath/xml/JDOMParser.java b/src/main/java/org/apache/commons/jxpath/xml/JDOMParser.java index a10122cdd..bddea63a7 100644 --- a/src/main/java/org/apache/commons/jxpath/xml/JDOMParser.java +++ b/src/main/java/org/apache/commons/jxpath/xml/JDOMParser.java @@ -19,8 +19,13 @@ import java.io.InputStream; +import javax.xml.parsers.SAXParserFactory; + import org.apache.commons.jxpath.JXPathException; +import org.apache.commons.xml.secure.SecureSAXParserFactory; +import org.jdom.JDOMException; import org.jdom.input.SAXBuilder; +import org.xml.sax.XMLReader; /** * An implementation of the XMLParser interface that produces a JDOM Document. @@ -40,7 +45,19 @@ public Object parseXML(final InputStream stream) { throw new JXPathException("JDOM parser configuration error. JDOM does not support the namespaceAware=false setting."); } try { - final SAXBuilder builder = new SAXBuilder(); + // JDOM builds its reader through JAXP internally; hand it one from the secure factory instead. + final SAXBuilder builder = new SAXBuilder() { + @Override + protected XMLReader createParser() throws JDOMException { + try { + final SAXParserFactory factory = SecureSAXParserFactory.newNSInstance(); + factory.setValidating(isValidating()); + return factory.newSAXParser().getXMLReader(); + } catch (final Exception ex) { + throw new JDOMException("Unable to create a new XML reader", ex); + } + } + }; builder.setExpandEntities(isExpandEntityReferences()); builder.setIgnoringElementContentWhitespace(isIgnoringElementContentWhitespace()); builder.setValidation(isValidating());