Skip to content

Commit

Permalink
Harden usage of XML document builder in build-conventions (elastic#10…
Browse files Browse the repository at this point in the history
…6874)

While `LicenseHeadersTask` only uses `DocumentBuilderFactory` internally
to parse `rat.xml` files (which are the output of running Apache RAT on
Elasticsearch codebase files), it is a good practice to disable XXE
features even if it's part of checks that are run on developers
machines.
  • Loading branch information
slobodanadamovic authored Mar 31, 2024
1 parent 64847b3 commit b643aba
Showing 1 changed file with 22 additions and 5 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -25,6 +25,7 @@
import org.gradle.api.file.FileCollection;
import org.gradle.api.file.ProjectLayout;
import org.gradle.api.file.RegularFileProperty;
import org.gradle.api.model.ObjectFactory;
import org.gradle.api.provider.ListProperty;
import org.gradle.api.tasks.CacheableTask;
import org.gradle.api.tasks.IgnoreEmptyDirectories;
Expand All @@ -39,21 +40,22 @@
import org.w3c.dom.Element;
import org.w3c.dom.NodeList;
import org.xml.sax.SAXException;
import org.gradle.api.model.ObjectFactory;
import javax.xml.parsers.DocumentBuilderFactory;
import javax.xml.parsers.ParserConfigurationException;

import java.io.BufferedWriter;
import java.io.File;
import java.io.FileWriter;
import java.io.IOException;
import java.io.Serializable;
import java.io.Writer;
import java.nio.file.Files;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;
import java.util.stream.Collectors;
import javax.inject.Inject;
import java.io.Serializable;
import javax.xml.XMLConstants;
import javax.xml.parsers.DocumentBuilderFactory;
import javax.xml.parsers.ParserConfigurationException;

/**
* Checks files for license headers..
Expand Down Expand Up @@ -232,7 +234,7 @@ private ClaimStatistic toXmlReportFile(ReportConfiguration config, Writer writer

private static List<String> unapprovedFiles(File xmlReportFile) {
try {
NodeList resourcesNodes = DocumentBuilderFactory.newInstance()
NodeList resourcesNodes = createXmlDocumentBuilderFactory()
.newDocumentBuilder()
.parse(xmlReportFile)
.getElementsByTagName("resource");
Expand All @@ -249,6 +251,21 @@ private static List<String> unapprovedFiles(File xmlReportFile) {
}
}

private static DocumentBuilderFactory createXmlDocumentBuilderFactory() throws ParserConfigurationException {
final DocumentBuilderFactory dbf = DocumentBuilderFactory.newInstance();
dbf.setXIncludeAware(false);
dbf.setIgnoringComments(true);
dbf.setExpandEntityReferences(false);
dbf.setAttribute(XMLConstants.ACCESS_EXTERNAL_DTD, "");
dbf.setAttribute(XMLConstants.ACCESS_EXTERNAL_SCHEMA, "");
dbf.setFeature(XMLConstants.FEATURE_SECURE_PROCESSING, 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;
}

private static List<Element> elementList(NodeList resourcesNodes) {
List<Element> nodeList = new ArrayList<>(resourcesNodes.getLength());
for (int idx = 0; idx < resourcesNodes.getLength(); idx++) {
Expand Down

0 comments on commit b643aba

Please sign in to comment.