|
39 | 39 | import java.util.Locale; |
40 | 40 | import java.util.Properties; |
41 | 41 |
|
| 42 | +import javax.xml.XMLConstants; |
42 | 43 | import javax.xml.parsers.DocumentBuilderFactory; |
| 44 | +import javax.xml.parsers.ParserConfigurationException; |
43 | 45 | import javax.xml.xpath.XPathConstants; |
44 | 46 | import javax.xml.xpath.XPathFactory; |
45 | 47 |
|
| 48 | +import javax.xml.xpath.XPathFactoryConfigurationException; |
46 | 49 | import org.w3c.dom.Document; |
47 | 50 |
|
48 | 51 | import io.github.classgraph.ClassGraph; |
@@ -221,9 +224,9 @@ public static synchronized String getVersion() { |
221 | 224 | for (int i = 0; i < 3 && path != null; i++, path = path.getParent()) { |
222 | 225 | final Path pom = path.resolve("pom.xml"); |
223 | 226 | try (InputStream is = Files.newInputStream(pom)) { |
224 | | - final Document doc = DocumentBuilderFactory.newInstance().newDocumentBuilder().parse(is); |
| 227 | + final Document doc = getSecureDocumentBuilderFactory().newDocumentBuilder().parse(is); |
225 | 228 | doc.getDocumentElement().normalize(); |
226 | | - String version = (String) XPathFactory.newInstance().newXPath().compile("/project/version") |
| 229 | + String version = (String) getSecureXPathFactory().newXPath().compile("/project/version") |
227 | 230 | .evaluate(doc, XPathConstants.STRING); |
228 | 231 | if (version != null) { |
229 | 232 | version = version.trim(); |
@@ -276,4 +279,40 @@ public static synchronized String getVersion() { |
276 | 279 | } |
277 | 280 | return "unknown"; |
278 | 281 | } |
| 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 | + } |
279 | 318 | } |
0 commit comments