CVE-2021-47621 (published 2024-06-21T06:15Z)

ClassGraph before 4.8.112 was not resistant to XML eXternal Entity (XXE) attacks.


Weakness information:
cwe_id: NVD-CWE-noinfo
cwe_name: Insufficient Information
description: There is insufficient information about the issue to classify it; details are unkown or unspecified.
extended_description: Insufficient Information

Fix information:
repo_url: https://github.com/classgraph/classgraph
commit_details: repo_url: https://github.com/classgraph/classgraph
author: Kshitiz Garg
author_date: 2021-08-05 14:05:06+05:30
msg: Adding SecureDocumentBuilderFactory & SecureXPATHFactory to prevent XXE( XML External Entity) attack
repository: repo_url: https://github.com/classgraph/classgraph
repo_name: classgraph/classgraph
description: An uber-fast parallelized Java classpath scanner and module scanner.
repo_language: Java
owner: classgraph
file_changes: filename: VersionFinder.java
change_type: ModificationType.MODIFY
diff: @@ -39,10 +39,13 @@ import java.util.List;
 import java.util.Locale;
 import java.util.Properties;
 
+import javax.xml.XMLConstants;
 import javax.xml.parsers.DocumentBuilderFactory;
+import javax.xml.parsers.ParserConfigurationException;
 import javax.xml.xpath.XPathConstants;
 import javax.xml.xpath.XPathFactory;
 
+import javax.xml.xpath.XPathFactoryConfigurationException;
 import org.w3c.dom.Document;
 
 import io.github.classgraph.ClassGraph;
@@ -221,9 +224,9 @@ public final class VersionFinder {
                 for (int i = 0; i < 3 && path != null; i++, path = path.getParent()) {
                     final Path pom = path.resolve("pom.xml");
                     try (InputStream is = Files.newInputStream(pom)) {
-                        final Document doc = DocumentBuilderFactory.newInstance().newDocumentBuilder().parse(is);
+                        final Document doc = getSecureDocumentBuilderFactory().newDocumentBuilder().parse(is);
                         doc.getDocumentElement().normalize();
-                        String version = (String) XPathFactory.newInstance().newXPath().compile("/project/version")
+                        String version = (String) getSecureXPathFactory().newXPath().compile("/project/version")
                                 .evaluate(doc, XPathConstants.STRING);
                         if (version != null) {
                             version = version.trim();
@@ -276,4 +279,40 @@ public final class VersionFinder {
         }
         return "unknown";
     }
+
+    /**
+     * Helper method to provide a XXE secured DocumentBuilder Factory.
+     *
+     * reference - https://gist.github.com/AlainODea/1779a7c6a26a5c135280bc9b3b71868f
+     * reference - https://rules.sonarsource.com/java/tag/owasp/RSPEC-2755
+     * @return DocumentBuilderFactory
+     * @throws ParserConfigurationException
+     */
+    private static DocumentBuilderFactory getSecureDocumentBuilderFactory() throws ParserConfigurationException {
+        DocumentBuilderFactory dbf = DocumentBuilderFactory.newInstance();
+        dbf.setXIncludeAware(false);
+        dbf.setFeature(XMLConstants.FEATURE_SECURE_PROCESSING, true);
+        dbf.setAttribute(XMLConstants.ACCESS_EXTERNAL_DTD, "");
+        dbf.setAttribute(XMLConstants.ACCESS_EXTERNAL_SCHEMA, "");
+        dbf.setExpandEntityReferences(false);
+        dbf.setNamespaceAware(true);
+        dbf.setFeature("http://apache.org/xml/features/disallow-doctype-decl", true);
+        dbf.setFeature("http://xml.org/sax/features/external-general-entities", false);
+        dbf.setFeature("http://xml.org/sax/features/external-parameter-entities", false);
+        dbf.setFeature("http://apache.org/xml/features/nonvalidating/load-external-dtd", false);
+        return dbf;
+    }
+
+    /**
+     * Helper method to provide a XXE secured XPathFactory Factory.
+     *
+     * reference - reference - https://rules.sonarsource.com/java/tag/owasp/RSPEC-2755
+     * @return XPathFactory
+     * @throws XPathFactoryConfigurationException
+     */
+    private static XPathFactory getSecureXPathFactory() throws XPathFactoryConfigurationException {
+        XPathFactory xPathFactory = XPathFactory.newInstance();
+        xPathFactory.setFeature(XMLConstants.FEATURE_SECURE_PROCESSING, true);
+        return xPathFactory;
+    }
 }

programming_language: Java