From a9160d06bf5b8c9c11666ab408ea8a09afa108a9 Mon Sep 17 00:00:00 2001
From: Mikolaj Izdebski <mizdebsk@redhat.com>
Date: Tue, 2 Apr 2019 15:10:53 +0200
Subject: [PATCH] Do not load external DTDs by default

---
 .../tools/checkstyle/api/AbstractLoader.java  | 43 ++++++++++++++++++-
 1 file changed, 41 insertions(+), 2 deletions(-)

diff --git a/src/main/java/com/puppycrawl/tools/checkstyle/api/AbstractLoader.java b/src/main/java/com/puppycrawl/tools/checkstyle/api/AbstractLoader.java
index a414492f3..76c72b767 100644
--- a/src/main/java/com/puppycrawl/tools/checkstyle/api/AbstractLoader.java
+++ b/src/main/java/com/puppycrawl/tools/checkstyle/api/AbstractLoader.java
@@ -83,8 +83,7 @@ public abstract class AbstractLoader
             throws SAXException, ParserConfigurationException {
         this.publicIdToResourceNameMap = new HashMap<>(publicIdToResourceNameMap);
         final SAXParserFactory factory = SAXParserFactory.newInstance();
-        factory.setFeature(LOAD_EXTERNAL_DTD, true);
-        factory.setFeature(EXTERNAL_GENERAL_ENTITIES, true);
+        LoadExternalDtdFeatureProvider.setFeaturesBySystemProperty(factory);
         factory.setValidating(true);
         factory.setNamespaceAware(true);
         parser = factory.newSAXParser().getXMLReader();
@@ -133,4 +132,44 @@ public abstract class AbstractLoader
     public void fatalError(SAXParseException exception) throws SAXException {
         throw exception;
     }
+
+    /**
+     * Used for setting specific for secure java installations features to SAXParserFactory.
+     * Pulled out as a separate class in order to suppress Pitest mutations.
+     */
+    public static final class LoadExternalDtdFeatureProvider {
+
+        /** System property name to enable external DTD load. */
+        public static final String ENABLE_EXTERNAL_DTD_LOAD = "checkstyle.enableExternalDtdLoad";
+
+        /** Feature that enables loading external DTD when loading XML files. */
+        private static final String LOAD_EXTERNAL_DTD =
+                "http://apache.org/xml/features/nonvalidating/load-external-dtd";
+        /** Feature that enables including external general entities in XML files. */
+        private static final String EXTERNAL_GENERAL_ENTITIES =
+                "http://xml.org/sax/features/external-general-entities";
+
+        /** Stop instances being created. **/
+        private LoadExternalDtdFeatureProvider() {
+        }
+
+        /**
+         * Configures SAXParserFactory with features required
+         * to use external DTD file loading, this is not activated by default to no allow
+         * usage of schema files that checkstyle do not know
+         * it is even security problem to allow files from outside.
+         * @param factory factory to be configured with special features
+         * @throws SAXException if an error occurs
+         * @throws ParserConfigurationException if an error occurs
+         */
+        public static void setFeaturesBySystemProperty(SAXParserFactory factory)
+                throws SAXException, ParserConfigurationException {
+
+            final boolean enableExternalDtdLoad = Boolean.valueOf(
+                System.getProperty(ENABLE_EXTERNAL_DTD_LOAD, "false"));
+
+            factory.setFeature(LOAD_EXTERNAL_DTD, enableExternalDtdLoad);
+            factory.setFeature(EXTERNAL_GENERAL_ENTITIES, enableExternalDtdLoad);
+        }
+    }
 }
-- 
2.20.1

