This is an automated email from the ASF dual-hosted git repository.
jbonofre pushed a commit to branch activemq-6.1.x
in repository https://gitbox.apache.org/repos/asf/activemq.git
The following commit(s) were added to refs/heads/activemq-6.1.x by this push:
new a8dad110d7 [AMQ-9783] Centralize XML safe parsing settings in a single
class. (#1508)
a8dad110d7 is described below
commit a8dad110d7141b8b80dcf7f84fb1ab30c24dda2b
Author: Sérgio Lemos <[email protected]>
AuthorDate: Fri Oct 17 08:35:57 2025 -0700
[AMQ-9783] Centralize XML safe parsing settings in a single class. (#1508)
---
.../org/apache/activemq/util/XmlFactories.java | 76 ++++++++++++++++++++++
.../activemq/console/command/CreateCommand.java | 19 ++----
.../plugin/RuntimeConfigurationBroker.java | 5 +-
3 files changed, 84 insertions(+), 16 deletions(-)
diff --git
a/activemq-broker/src/main/java/org/apache/activemq/util/XmlFactories.java
b/activemq-broker/src/main/java/org/apache/activemq/util/XmlFactories.java
new file mode 100644
index 0000000000..bef972c96c
--- /dev/null
+++ b/activemq-broker/src/main/java/org/apache/activemq/util/XmlFactories.java
@@ -0,0 +1,76 @@
+/**
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.apache.activemq.util;
+
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+import javax.xml.XMLConstants;
+import javax.xml.parsers.DocumentBuilderFactory;
+import javax.xml.parsers.ParserConfigurationException;
+import javax.xml.transform.TransformerConfigurationException;
+import javax.xml.transform.TransformerFactory;
+
+/**
+ * Utility class to obtain XML-processing related factories with
pre-configured safe parameters. Prefer to centralize
+ * these parameters here instead of doing ad-hoc on several places.
+ */
+public final class XmlFactories {
+ private static final Logger LOG =
LoggerFactory.getLogger(XmlFactories.class);
+
+ private XmlFactories() { /* Do not instantiate */ }
+
+ public static DocumentBuilderFactory getSafeDocumentBuilderFactory() {
+ DocumentBuilderFactory builderFactory =
DocumentBuilderFactory.newInstance();
+
+ // See
https://github.com/OWASP/CheatSheetSeries/blob/master/cheatsheets/XML_External_Entity_Prevention_Cheat_Sheet.md#java
+ trySetFeature(builderFactory, XMLConstants.FEATURE_SECURE_PROCESSING,
true);
+
trySetFeature(builderFactory,"http://apache.org/xml/features/disallow-doctype-decl",
true);
+
trySetFeature(builderFactory,"http://xml.org/sax/features/external-general-entities",
false);
+
trySetFeature(builderFactory,"http://xml.org/sax/features/external-parameter-entities",
false);
+
trySetFeature(builderFactory,"http://apache.org/xml/features/nonvalidating/load-external-dtd",
false);
+
+ return builderFactory;
+ }
+
+ public static TransformerFactory getSafeTransformFactory() {
+ TransformerFactory transformerFactory =
TransformerFactory.newInstance();
+ trySetFeature(transformerFactory,
XMLConstants.FEATURE_SECURE_PROCESSING, true);
+
+ // See
https://github.com/OWASP/CheatSheetSeries/blob/master/cheatsheets/XML_External_Entity_Prevention_Cheat_Sheet.md#transformerfactory
+ transformerFactory.setAttribute(XMLConstants.ACCESS_EXTERNAL_DTD, "");
+
transformerFactory.setAttribute(XMLConstants.ACCESS_EXTERNAL_STYLESHEET, "");
+
+ return transformerFactory;
+ }
+
+ private static void trySetFeature(final DocumentBuilderFactory factory,
final String name, final boolean value) {
+ try {
+ factory.setFeature(name, value);
+ } catch (final ParserConfigurationException e) {
+ LOG.warn("Error setting document builder factory feature", e);
+ }
+ }
+
+ private static void trySetFeature(final TransformerFactory factory, final
String name, final boolean value) {
+ try {
+ factory.setFeature(name, value);
+ } catch (final TransformerConfigurationException e) {
+ LOG.warn("Error setting transformer factory feature", e);
+ }
+ }
+}
diff --git
a/activemq-console/src/main/java/org/apache/activemq/console/command/CreateCommand.java
b/activemq-console/src/main/java/org/apache/activemq/console/command/CreateCommand.java
index c1c8685f45..f976b4ee10 100644
---
a/activemq-console/src/main/java/org/apache/activemq/console/command/CreateCommand.java
+++
b/activemq-console/src/main/java/org/apache/activemq/console/command/CreateCommand.java
@@ -16,13 +16,12 @@
*/
package org.apache.activemq.console.command;
+import org.apache.activemq.util.XmlFactories;
import org.w3c.dom.Attr;
import org.w3c.dom.Element;
import org.xml.sax.SAXException;
-import javax.xml.XMLConstants;
import javax.xml.parsers.DocumentBuilder;
-import javax.xml.parsers.DocumentBuilderFactory;
import javax.xml.parsers.ParserConfigurationException;
import javax.xml.transform.*;
import javax.xml.transform.dom.DOMSource;
@@ -159,10 +158,7 @@ public class CreateCommand extends AbstractCommand {
File dest = new File(targetBase, DEFAULT_TARGET_ACTIVEMQ_CONF);
context.print("Copying from: " + src.getCanonicalPath() + "\n
to: " + dest.getCanonicalPath());
- DocumentBuilderFactory dbf = DocumentBuilderFactory.newInstance();
- dbf.setFeature(XMLConstants.FEATURE_SECURE_PROCESSING, Boolean.TRUE);
- dbf.setFeature("http://apache.org/xml/features/disallow-doctype-decl",
true);
- DocumentBuilder builder = dbf.newDocumentBuilder();
+ DocumentBuilder builder =
XmlFactories.getSafeDocumentBuilderFactory().newDocumentBuilder();
Element docElem = builder.parse(src).getDocumentElement();
XPath xpath = XPathFactory.newInstance().newXPath();
@@ -208,13 +204,10 @@ public class CreateCommand extends AbstractCommand {
// utlity method to write an xml source to file
private void writeToFile(Source src, File file) throws
TransformerException {
- TransformerFactory tFactory = TransformerFactory.newInstance();
- tFactory.setFeature(javax.xml.XMLConstants.FEATURE_SECURE_PROCESSING,
Boolean.TRUE);
-
- Transformer fileTransformer = tFactory.newTransformer();
-
- Result res = new StreamResult(file);
- fileTransformer.transform(src, res);
+ final Result res = new StreamResult(file);
+ XmlFactories.getSafeTransformFactory()
+ .newTransformer()
+ .transform(src, res);
}
// utility method to copy one file to another
diff --git
a/activemq-runtime-config/src/main/java/org/apache/activemq/plugin/RuntimeConfigurationBroker.java
b/activemq-runtime-config/src/main/java/org/apache/activemq/plugin/RuntimeConfigurationBroker.java
index b7342f417d..27fd410c64 100644
---
a/activemq-runtime-config/src/main/java/org/apache/activemq/plugin/RuntimeConfigurationBroker.java
+++
b/activemq-runtime-config/src/main/java/org/apache/activemq/plugin/RuntimeConfigurationBroker.java
@@ -42,6 +42,7 @@ import org.apache.activemq.broker.jmx.ManagementContext;
import org.apache.activemq.plugin.jmx.RuntimeConfigurationView;
import org.apache.activemq.schema.core.DtoBroker;
import org.apache.activemq.spring.Utils;
+import org.apache.activemq.util.XmlFactories;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.core.io.Resource;
@@ -178,10 +179,8 @@ public class RuntimeConfigurationBroker extends
AbstractRuntimeConfigurationBrok
unMarshaller.setSchema(getSchema());
// skip beans and pull out the broker node to validate
- DocumentBuilderFactory dbf =
DocumentBuilderFactory.newInstance();
+ DocumentBuilderFactory dbf =
XmlFactories.getSafeDocumentBuilderFactory();
dbf.setNamespaceAware(true);
- dbf.setFeature(XMLConstants.FEATURE_SECURE_PROCESSING,
Boolean.TRUE);
-
dbf.setFeature("http://apache.org/xml/features/disallow-doctype-decl", true);
DocumentBuilder db = dbf.newDocumentBuilder();
Document doc = db.parse(configToMonitor.getInputStream());
---------------------------------------------------------------------
To unsubscribe, e-mail: [email protected]
For additional commands, e-mail: [email protected]
For further information, visit: https://activemq.apache.org/contact