VYPR
Critical severity9.8NVD Advisory· Published Oct 27, 2017· Updated May 13, 2026

CVE-2014-3600

CVE-2014-3600

Description

XML external entity (XXE) vulnerability in Apache ActiveMQ 5.x before 5.10.1 allows remote consumers to have unspecified impact via vectors involving an XPath based selector when dequeuing XML messages.

Affected packages

Versions sourced from the GitHub Security Advisory.

PackageAffected versionsPatched versions
org.apache.activemq:activemq-clientMaven
>= 5.0.0, < 5.10.15.10.1
org.apache.activemq:activemq-brokerMaven
>= 5.0.0, < 5.10.15.10.1

Affected products

18
  • Apache/Activemq18 versions
    cpe:2.3:a:apache:activemq:5.0.0:*:*:*:*:*:*:*+ 17 more
    • cpe:2.3:a:apache:activemq:5.0.0:*:*:*:*:*:*:*
    • cpe:2.3:a:apache:activemq:5.1.0:*:*:*:*:*:*:*
    • cpe:2.3:a:apache:activemq:5.10.0:*:*:*:*:*:*:*
    • cpe:2.3:a:apache:activemq:5.2.0:*:*:*:*:*:*:*
    • cpe:2.3:a:apache:activemq:5.3.0:*:*:*:*:*:*:*
    • cpe:2.3:a:apache:activemq:5.3.1:*:*:*:*:*:*:*
    • cpe:2.3:a:apache:activemq:5.3.2:*:*:*:*:*:*:*
    • cpe:2.3:a:apache:activemq:5.4.0:*:*:*:*:*:*:*
    • cpe:2.3:a:apache:activemq:5.4.1:*:*:*:*:*:*:*
    • cpe:2.3:a:apache:activemq:5.4.2:*:*:*:*:*:*:*
    • cpe:2.3:a:apache:activemq:5.4.3:*:*:*:*:*:*:*
    • cpe:2.3:a:apache:activemq:5.5.0:*:*:*:*:*:*:*
    • cpe:2.3:a:apache:activemq:5.5.1:*:*:*:*:*:*:*
    • cpe:2.3:a:apache:activemq:5.6.0:*:*:*:*:*:*:*
    • cpe:2.3:a:apache:activemq:5.7.0:*:*:*:*:*:*:*
    • cpe:2.3:a:apache:activemq:5.8.0:*:*:*:*:*:*:*
    • cpe:2.3:a:apache:activemq:5.9.0:*:*:*:*:*:*:*
    • cpe:2.3:a:apache:activemq:5.9.1:*:*:*:*:*:*:*

Patches

1
3e5ac6326db5

https://issues.apache.org/jira/browse/AMQ-5333 - make xpath parser features configurable

https://github.com/apache/activemqDejan BosanacAug 26, 2014via ghsa
3 files changed · +94 37
  • activemq-broker/src/main/java/org/apache/activemq/filter/JAXPXPathEvaluator.java+20 17 modified
    @@ -16,32 +16,33 @@
      */
     package org.apache.activemq.filter;
     
    -import java.io.StringReader;
    +import org.apache.activemq.command.Message;
    +import org.apache.activemq.util.ByteArrayInputStream;
    +import org.w3c.dom.Document;
    +import org.xml.sax.InputSource;
    +
     import javax.jms.BytesMessage;
     import javax.jms.JMSException;
     import javax.jms.TextMessage;
    +import javax.xml.parsers.DocumentBuilder;
     import javax.xml.xpath.XPath;
     import javax.xml.xpath.XPathConstants;
    -import javax.xml.xpath.XPathExpressionException;
     import javax.xml.xpath.XPathFactory;
    -
    -import org.apache.activemq.command.Message;
    -import org.apache.activemq.util.ByteArrayInputStream;
    -import org.xml.sax.InputSource;
    +import java.io.StringReader;
     
     public class JAXPXPathEvaluator implements XPathExpression.XPathEvaluator {
     
         private static final XPathFactory FACTORY = XPathFactory.newInstance();
    -    private final javax.xml.xpath.XPathExpression expression;
         private final String xpathExpression;
    +    private final DocumentBuilder builder;
    +    private final XPath xpath = FACTORY.newXPath();
     
    -    public JAXPXPathEvaluator(String xpathExpression) {
    +    public JAXPXPathEvaluator(String xpathExpression, DocumentBuilder builder) throws Exception {
             this.xpathExpression = xpathExpression;
    -        try {
    -            XPath xpath = FACTORY.newXPath();
    -            expression = xpath.compile(xpathExpression);
    -        } catch (XPathExpressionException e) {
    -            throw new RuntimeException("Invalid XPath expression: " + xpathExpression);
    +        if (builder != null) {
    +            this.builder = builder;
    +        } else {
    +            throw new RuntimeException("No document builder available");
             }
         }
     
    @@ -61,17 +62,19 @@ public boolean evaluate(Message message) throws JMSException {
         private boolean evaluate(byte[] data) {
             try {
                 InputSource inputSource = new InputSource(new ByteArrayInputStream(data));
    -            return ((Boolean)expression.evaluate(inputSource, XPathConstants.BOOLEAN)).booleanValue();
    -        } catch (XPathExpressionException e) {
    +            Document inputDocument = builder.parse(inputSource);
    +            return ((Boolean)xpath.evaluate(xpathExpression, inputDocument, XPathConstants.BOOLEAN)).booleanValue();
    +        } catch (Exception e) {
                 return false;
             }
         }
     
         private boolean evaluate(String text) {
             try {
                 InputSource inputSource = new InputSource(new StringReader(text));
    -            return ((Boolean)expression.evaluate(inputSource, XPathConstants.BOOLEAN)).booleanValue();
    -        } catch (XPathExpressionException e) {
    +            Document inputDocument = builder.parse(inputSource);
    +            return ((Boolean)xpath.evaluate(xpathExpression, inputDocument, XPathConstants.BOOLEAN)).booleanValue();
    +        } catch (Exception e) {
                 return false;
             }
         }
    
  • activemq-broker/src/main/java/org/apache/activemq/filter/XalanXPathEvaluator.java+19 18 modified
    @@ -16,34 +16,33 @@
      */
     package org.apache.activemq.filter;
     
    -import java.io.StringReader;
    +import org.apache.activemq.command.Message;
    +import org.apache.activemq.util.ByteArrayInputStream;
    +import org.w3c.dom.Document;
    +import org.xml.sax.InputSource;
     
     import javax.jms.BytesMessage;
     import javax.jms.JMSException;
     import javax.jms.TextMessage;
    +import javax.xml.parsers.DocumentBuilder;
     import javax.xml.xpath.XPath;
     import javax.xml.xpath.XPathConstants;
    -import javax.xml.xpath.XPathExpressionException;
     import javax.xml.xpath.XPathFactory;
    -
    -import org.apache.activemq.command.Message;
    -import org.apache.activemq.util.ByteArrayInputStream;
    -
    -import org.xml.sax.InputSource;
    +import java.io.StringReader;
     
     public class XalanXPathEvaluator implements XPathExpression.XPathEvaluator {
     
         private static final XPathFactory FACTORY = XPathFactory.newInstance();
    -    private final javax.xml.xpath.XPathExpression expression;
         private final String xpathExpression;
    +    private final DocumentBuilder builder;
    +    private final XPath xpath = FACTORY.newXPath();
     
    -    public XalanXPathEvaluator(String xpathExpression) {
    +    public XalanXPathEvaluator(String xpathExpression, DocumentBuilder builder) throws Exception {
             this.xpathExpression = xpathExpression;
    -        try {
    -            XPath xpath = FACTORY.newXPath();
    -            expression = xpath.compile(xpathExpression);
    -        } catch (XPathExpressionException e) {
    -            throw new RuntimeException("Invalid XPath expression: " + xpathExpression);
    +        if (builder != null) {
    +            this.builder = builder;
    +        } else {
    +            throw new RuntimeException("No document builder available");
             }
         }
     
    @@ -63,17 +62,19 @@ public boolean evaluate(Message message) throws JMSException {
         private boolean evaluate(byte[] data) {
             try {
                 InputSource inputSource = new InputSource(new ByteArrayInputStream(data));
    -            return ((Boolean)expression.evaluate(inputSource, XPathConstants.BOOLEAN)).booleanValue();
    -        } catch (XPathExpressionException e) {
    +            Document inputDocument = builder.parse(inputSource);
    +            return ((Boolean) xpath.evaluate(xpathExpression, inputDocument, XPathConstants.BOOLEAN)).booleanValue();
    +        } catch (Exception e) {
                 return false;
             }
         }
     
         private boolean evaluate(String text) {
             try {
                 InputSource inputSource = new InputSource(new StringReader(text));
    -            return ((Boolean)expression.evaluate(inputSource, XPathConstants.BOOLEAN)).booleanValue();
    -        } catch (XPathExpressionException e) {
    +            Document inputDocument = builder.parse(inputSource);
    +            return ((Boolean) xpath.evaluate(xpathExpression, inputDocument, XPathConstants.BOOLEAN)).booleanValue();
    +        } catch (Exception e) {
                 return false;
             }
         }
    
  • activemq-client/src/main/java/org/apache/activemq/filter/XPathExpression.java+55 2 modified
    @@ -19,8 +19,15 @@
     import java.io.IOException;
     import java.lang.reflect.Constructor;
     import java.lang.reflect.InvocationTargetException;
    +import java.util.ArrayList;
    +import java.util.List;
    +import java.util.Map;
    +import java.util.Properties;
     
     import javax.jms.JMSException;
    +import javax.xml.parsers.DocumentBuilder;
    +import javax.xml.parsers.DocumentBuilderFactory;
    +import javax.xml.parsers.ParserConfigurationException;
     
     import org.apache.activemq.command.Message;
     import org.apache.activemq.util.JMSExceptionSupport;
    @@ -35,15 +42,32 @@ public final class XPathExpression implements BooleanExpression {
         private static final Logger LOG = LoggerFactory.getLogger(XPathExpression.class);
         private static final String EVALUATOR_SYSTEM_PROPERTY = "org.apache.activemq.XPathEvaluatorClassName";
         private static final String DEFAULT_EVALUATOR_CLASS_NAME = "org.apache.activemq.filter.XalanXPathEvaluator";
    +    public static final String DOCUMENT_BUILDER_FACTORY_FEATURE = "org.apache.activemq.documentBuilderFactory.feature";
     
         private static final Constructor EVALUATOR_CONSTRUCTOR;
    +    private static DocumentBuilder builder = null;
     
         static {
             String cn = System.getProperty(EVALUATOR_SYSTEM_PROPERTY, DEFAULT_EVALUATOR_CLASS_NAME);
             Constructor m = null;
             try {
                 try {
                     m = getXPathEvaluatorConstructor(cn);
    +                DocumentBuilderFactory builderFactory = DocumentBuilderFactory.newInstance();
    +                builderFactory.setNamespaceAware(true);
    +                builderFactory.setIgnoringElementContentWhitespace(true);
    +                builderFactory.setIgnoringComments(true);
    +                try {
    +                    // set some reasonable defaults
    +                    builderFactory.setFeature("http://xml.org/sax/features/external-general-entities", false);
    +                    builderFactory.setFeature("http://xml.org/sax/features/external-parameter-entities", false);
    +                    builderFactory.setFeature("http://apache.org/xml/features/disallow-doctype-decl", true);
    +                } catch (ParserConfigurationException e) {
    +                    LOG.warn("Error setting document builder factory feature", e);
    +                }
    +                // setup the feature from the system property
    +                setupFeatures(builderFactory);
    +                builder = builderFactory.newDocumentBuilder();
                 } catch (Throwable e) {
                     LOG.warn("Invalid " + XPathEvaluator.class.getName() + " implementation: " + cn + ", reason: " + e, e);
                     cn = DEFAULT_EVALUATOR_CLASS_NAME;
    @@ -75,12 +99,41 @@ private static Constructor getXPathEvaluatorConstructor(String cn) throws ClassN
             if (!XPathEvaluator.class.isAssignableFrom(c)) {
                 throw new ClassCastException("" + c + " is not an instance of " + XPathEvaluator.class);
             }
    -        return c.getConstructor(new Class[] {String.class});
    +        return c.getConstructor(new Class[] {String.class, DocumentBuilder.class});
    +    }
    +
    +    protected static void setupFeatures(DocumentBuilderFactory factory) {
    +        Properties properties = System.getProperties();
    +        List<String> features = new ArrayList<String>();
    +        for (Map.Entry<Object, Object> prop : properties.entrySet()) {
    +            String key = (String) prop.getKey();
    +            if (key.startsWith(DOCUMENT_BUILDER_FACTORY_FEATURE)) {
    +                String uri = key.split(DOCUMENT_BUILDER_FACTORY_FEATURE + ":")[1];
    +                Boolean value = Boolean.valueOf((String)prop.getValue());
    +                try {
    +                    factory.setFeature(uri, value);
    +                    features.add("feature " + uri + " value " + value);
    +                } catch (ParserConfigurationException e) {
    +                    LOG.warn("DocumentBuilderFactory doesn't support the feature {} with value {}, due to {}.", new Object[]{uri, value, e});
    +                }
    +            }
    +        }
    +        if (features.size() > 0) {
    +            StringBuffer featureString = new StringBuffer();
    +            // just log the configured feature
    +            for (String feature : features) {
    +                if (featureString.length() != 0) {
    +                    featureString.append(", ");
    +                }
    +                featureString.append(feature);
    +            }
    +        }
    +
         }
     
         private XPathEvaluator createEvaluator(String xpath2) {
             try {
    -            return (XPathEvaluator)EVALUATOR_CONSTRUCTOR.newInstance(new Object[] {xpath});
    +            return (XPathEvaluator)EVALUATOR_CONSTRUCTOR.newInstance(new Object[] {xpath, builder});
             } catch (InvocationTargetException e) {
                 Throwable cause = e.getCause();
                 if (cause instanceof RuntimeException) {
    

Vulnerability mechanics

Generated by null/stub on May 9, 2026. Inputs: CWE entries + fix-commit diffs from this CVE's patches. Citations validated against bundle.

References

10

News mentions

0

No linked articles in our index yet.