Skip to content

Commit 681362a

Browse files
author
Kshitiz Garg
committed
Adding SecureDocumentBuilderFactory & SecureXPATHFactory to prevent XXE( XML External Entity) attack
1 parent 71ba4a2 commit 681362a

File tree

1 file changed

+41
-2
lines changed

1 file changed

+41
-2
lines changed

Diff for: src/main/java/nonapi/io/github/classgraph/utils/VersionFinder.java

+41-2
Original file line numberDiff line numberDiff line change
@@ -39,10 +39,13 @@
3939
import java.util.Locale;
4040
import java.util.Properties;
4141

42+
import javax.xml.XMLConstants;
4243
import javax.xml.parsers.DocumentBuilderFactory;
44+
import javax.xml.parsers.ParserConfigurationException;
4345
import javax.xml.xpath.XPathConstants;
4446
import javax.xml.xpath.XPathFactory;
4547

48+
import javax.xml.xpath.XPathFactoryConfigurationException;
4649
import org.w3c.dom.Document;
4750

4851
import io.github.classgraph.ClassGraph;
@@ -221,9 +224,9 @@ public static synchronized String getVersion() {
221224
for (int i = 0; i < 3 && path != null; i++, path = path.getParent()) {
222225
final Path pom = path.resolve("pom.xml");
223226
try (InputStream is = Files.newInputStream(pom)) {
224-
final Document doc = DocumentBuilderFactory.newInstance().newDocumentBuilder().parse(is);
227+
final Document doc = getSecureDocumentBuilderFactory().newDocumentBuilder().parse(is);
225228
doc.getDocumentElement().normalize();
226-
String version = (String) XPathFactory.newInstance().newXPath().compile("/project/version")
229+
String version = (String) getSecureXPathFactory().newXPath().compile("/project/version")
227230
.evaluate(doc, XPathConstants.STRING);
228231
if (version != null) {
229232
version = version.trim();
@@ -276,4 +279,40 @@ public static synchronized String getVersion() {
276279
}
277280
return "unknown";
278281
}
282+
283+
/**
284+
* Helper method to provide a XXE secured DocumentBuilder Factory.
285+
*
286+
* reference - https://gist.github.com/AlainODea/1779a7c6a26a5c135280bc9b3b71868f
287+
* reference - https://rules.sonarsource.com/java/tag/owasp/RSPEC-2755
288+
* @return DocumentBuilderFactory
289+
* @throws ParserConfigurationException
290+
*/
291+
private static DocumentBuilderFactory getSecureDocumentBuilderFactory() throws ParserConfigurationException {
292+
DocumentBuilderFactory dbf = DocumentBuilderFactory.newInstance();
293+
dbf.setXIncludeAware(false);
294+
dbf.setFeature(XMLConstants.FEATURE_SECURE_PROCESSING, true);
295+
dbf.setAttribute(XMLConstants.ACCESS_EXTERNAL_DTD, "");
296+
dbf.setAttribute(XMLConstants.ACCESS_EXTERNAL_SCHEMA, "");
297+
dbf.setExpandEntityReferences(false);
298+
dbf.setNamespaceAware(true);
299+
dbf.setFeature("http://apache.org/xml/features/disallow-doctype-decl", true);
300+
dbf.setFeature("http://xml.org/sax/features/external-general-entities", false);
301+
dbf.setFeature("http://xml.org/sax/features/external-parameter-entities", false);
302+
dbf.setFeature("http://apache.org/xml/features/nonvalidating/load-external-dtd", false);
303+
return dbf;
304+
}
305+
306+
/**
307+
* Helper method to provide a XXE secured XPathFactory Factory.
308+
*
309+
* reference - reference - https://rules.sonarsource.com/java/tag/owasp/RSPEC-2755
310+
* @return XPathFactory
311+
* @throws XPathFactoryConfigurationException
312+
*/
313+
private static XPathFactory getSecureXPathFactory() throws XPathFactoryConfigurationException {
314+
XPathFactory xPathFactory = XPathFactory.newInstance();
315+
xPathFactory.setFeature(XMLConstants.FEATURE_SECURE_PROCESSING, true);
316+
return xPathFactory;
317+
}
279318
}

0 commit comments

Comments
 (0)