]> git.basschouten.com Git - openhab-addons.git/commitdiff
Merge pull request from GHSA-r2hc-pmr7-4c9r
authorKai Kreuzer <kai@openhab.org>
Sun, 24 Jan 2021 14:06:00 +0000 (15:06 +0100)
committerGitHub <noreply@github.com>
Sun, 24 Jan 2021 14:06:00 +0000 (15:06 +0100)
* Configured XML parsers to resist XXE attacks

Signed-off-by: Kai Kreuzer <kai@openhab.org>
* added fix for avmfritz

Signed-off-by: Kai Kreuzer <kai@openhab.org>
* added fix for sonos

Signed-off-by: Kai Kreuzer <kai@openhab.org>
* added fix for vitotronic and bosesoundtouch

Signed-off-by: Kai Kreuzer <kai@openhab.org>
* changed avmfritz to singleton pattern

Signed-off-by: Kai Kreuzer <kai@openhab.org>
* addressed roku binding

Signed-off-by: Kai Kreuzer <kai@openhab.org>
* address all uses of DocumentBuilderFactory

Signed-off-by: Kai Kreuzer <kai@openhab.org>
* fixed other occurrences in roku binding

Signed-off-by: Kai Kreuzer <kai@openhab.org>
33 files changed:
bundles/org.openhab.binding.avmfritz/src/main/java/org/openhab/binding/avmfritz/internal/hardware/callbacks/FritzAhaUpdateCallback.java
bundles/org.openhab.binding.avmfritz/src/main/java/org/openhab/binding/avmfritz/internal/hardware/callbacks/FritzAhaUpdateTemplatesCallback.java
bundles/org.openhab.binding.avmfritz/src/main/java/org/openhab/binding/avmfritz/internal/util/JAXBUtils.java
bundles/org.openhab.binding.bosesoundtouch/src/main/java/org/openhab/binding/bosesoundtouch/internal/XMLResponseProcessor.java
bundles/org.openhab.binding.denonmarantz/src/main/java/org/openhab/binding/denonmarantz/internal/connector/http/DenonMarantzHttpConnector.java
bundles/org.openhab.binding.denonmarantz/src/main/java/org/openhab/binding/denonmarantz/internal/handler/DenonMarantzHandler.java
bundles/org.openhab.binding.dlinksmarthome/src/main/java/org/openhab/binding/dlinksmarthome/internal/DLinkHNAPCommunication.java
bundles/org.openhab.binding.enigma2/src/main/java/org/openhab/binding/enigma2/internal/Enigma2Client.java
bundles/org.openhab.binding.fmiweather/src/main/java/org/openhab/binding/fmiweather/internal/client/Client.java
bundles/org.openhab.binding.fsinternetradio/src/main/java/org/openhab/binding/fsinternetradio/internal/radio/FrontierSiliconRadioApiResult.java
bundles/org.openhab.binding.gce/src/main/java/org/openhab/binding/gce/internal/model/StatusFileInterpreter.java
bundles/org.openhab.binding.homematic/src/main/java/org/openhab/binding/homematic/internal/communicator/message/XmlRpcResponse.java
bundles/org.openhab.binding.hpprinter/src/main/java/org/openhab/binding/hpprinter/internal/api/HPWebServerClient.java
bundles/org.openhab.binding.ihc/src/main/java/org/openhab/binding/ihc/internal/ws/projectfile/ProjectFileUtils.java
bundles/org.openhab.binding.insteon/src/main/java/org/openhab/binding/insteon/internal/device/DeviceTypeLoader.java
bundles/org.openhab.binding.insteon/src/main/java/org/openhab/binding/insteon/internal/device/FeatureTemplateLoader.java
bundles/org.openhab.binding.insteon/src/main/java/org/openhab/binding/insteon/internal/message/XMLMessageReader.java
bundles/org.openhab.binding.onkyo/src/main/java/org/openhab/binding/onkyo/internal/handler/OnkyoHandler.java
bundles/org.openhab.binding.roku/src/main/java/org/openhab/binding/roku/internal/communication/JAXBUtils.java
bundles/org.openhab.binding.roku/src/main/java/org/openhab/binding/roku/internal/communication/RokuCommunicator.java
bundles/org.openhab.binding.samsungtv/src/main/java/org/openhab/binding/samsungtv/internal/service/SamsungTvUtils.java
bundles/org.openhab.binding.sonos/src/main/java/org/openhab/binding/sonos/internal/SonosXMLParser.java
bundles/org.openhab.binding.tellstick/src/main/java/org/openhab/binding/tellstick/internal/live/TelldusLiveDeviceController.java
bundles/org.openhab.binding.tr064/src/main/java/org/openhab/binding/tr064/internal/phonebook/Tr064PhonebookImpl.java
bundles/org.openhab.binding.tr064/src/main/java/org/openhab/binding/tr064/internal/util/Util.java
bundles/org.openhab.binding.upnpcontrol/src/main/java/org/openhab/binding/upnpcontrol/internal/util/UpnpXMLParser.java
bundles/org.openhab.binding.vitotronic/src/main/java/org/openhab/binding/vitotronic/internal/handler/VitotronicBridgeHandler.java
bundles/org.openhab.binding.wemo/src/main/java/org/openhab/binding/wemo/internal/discovery/WemoLinkDiscoveryService.java
bundles/org.openhab.binding.wemo/src/main/java/org/openhab/binding/wemo/internal/handler/WemoCoffeeHandler.java
bundles/org.openhab.binding.wemo/src/main/java/org/openhab/binding/wemo/internal/handler/WemoHolmesHandler.java
bundles/org.openhab.binding.wemo/src/main/java/org/openhab/binding/wemo/internal/handler/WemoMakerHandler.java
bundles/org.openhab.binding.yamahareceiver/src/main/java/org/openhab/binding/yamahareceiver/internal/protocol/xml/XMLUtils.java
bundles/org.openhab.transform.xpath/src/main/java/org/openhab/transform/xpath/internal/XPathTransformationService.java

index 16bacbce5b5464db4fb44e3ca6f03e0ff691b567..31caca094143102ac9a502b60b37ad58a3ff9f49 100644 (file)
@@ -18,6 +18,8 @@ import java.io.StringReader;
 
 import javax.xml.bind.JAXBException;
 import javax.xml.bind.Unmarshaller;
+import javax.xml.stream.XMLStreamException;
+import javax.xml.stream.XMLStreamReader;
 
 import org.eclipse.jdt.annotation.NonNullByDefault;
 import org.openhab.binding.avmfritz.internal.dto.DeviceListModel;
@@ -62,15 +64,16 @@ public class FritzAhaUpdateCallback extends FritzAhaReauthCallback {
         logger.trace("Received State response {}", response);
         if (isValidRequest()) {
             try {
+                XMLStreamReader xsr = JAXBUtils.XMLINPUTFACTORY.createXMLStreamReader(new StringReader(response));
                 Unmarshaller unmarshaller = JAXBUtils.JAXBCONTEXT_DEVICES.createUnmarshaller();
-                DeviceListModel model = (DeviceListModel) unmarshaller.unmarshal(new StringReader(response));
+                DeviceListModel model = (DeviceListModel) unmarshaller.unmarshal(xsr);
                 if (model != null) {
                     handler.onDeviceListAdded(model.getDevicelist());
                 } else {
                     logger.debug("no model in response");
                 }
                 handler.setStatusInfo(ThingStatus.ONLINE, ThingStatusDetail.NONE, null);
-            } catch (JAXBException e) {
+            } catch (JAXBException | XMLStreamException e) {
                 logger.error("Exception creating Unmarshaller: {}", e.getLocalizedMessage(), e);
                 handler.setStatusInfo(ThingStatus.OFFLINE, ThingStatusDetail.COMMUNICATION_ERROR,
                         e.getLocalizedMessage());
index c3a47a033cf54fddb9cc880872bfd65182b83f38..d976c3b35e014219d6005fa11adc0547344d2e0a 100644 (file)
@@ -18,6 +18,8 @@ import java.io.StringReader;
 
 import javax.xml.bind.JAXBException;
 import javax.xml.bind.Unmarshaller;
+import javax.xml.stream.XMLStreamException;
+import javax.xml.stream.XMLStreamReader;
 
 import org.eclipse.jdt.annotation.NonNullByDefault;
 import org.openhab.binding.avmfritz.internal.dto.templates.TemplateListModel;
@@ -58,14 +60,15 @@ public class FritzAhaUpdateTemplatesCallback extends FritzAhaReauthCallback {
         logger.trace("Received response '{}'", response);
         if (isValidRequest()) {
             try {
+                XMLStreamReader xsr = JAXBUtils.XMLINPUTFACTORY.createXMLStreamReader(new StringReader(response));
                 Unmarshaller unmarshaller = JAXBUtils.JAXBCONTEXT_TEMPLATES.createUnmarshaller();
-                TemplateListModel model = (TemplateListModel) unmarshaller.unmarshal(new StringReader(response));
+                TemplateListModel model = (TemplateListModel) unmarshaller.unmarshal(xsr);
                 if (model != null) {
                     handler.addTemplateList(model.getTemplates());
                 } else {
                     logger.debug("no template in response");
                 }
-            } catch (JAXBException e) {
+            } catch (JAXBException | XMLStreamException e) {
                 logger.error("Exception creating Unmarshaller: {}", e.getLocalizedMessage(), e);
             }
         } else {
index 55d454f5b12b0cbbdfcbaa1e3a0156eff39690f6..742745396625f2f7b7b72fa4448082d448541575 100644 (file)
@@ -14,6 +14,7 @@ package org.openhab.binding.avmfritz.internal.util;
 
 import javax.xml.bind.JAXBContext;
 import javax.xml.bind.JAXBException;
+import javax.xml.stream.XMLInputFactory;
 
 import org.eclipse.jdt.annotation.NonNullByDefault;
 import org.eclipse.jdt.annotation.Nullable;
@@ -34,6 +35,7 @@ public class JAXBUtils {
 
     public static final @Nullable JAXBContext JAXBCONTEXT_DEVICES = initJAXBContextDevices();
     public static final @Nullable JAXBContext JAXBCONTEXT_TEMPLATES = initJAXBContextTemplates();
+    public static final XMLInputFactory XMLINPUTFACTORY = initXMLInputFactory();
 
     private static @Nullable JAXBContext initJAXBContextDevices() {
         try {
@@ -52,4 +54,11 @@ public class JAXBUtils {
             return null;
         }
     }
+
+    private static XMLInputFactory initXMLInputFactory() {
+        XMLInputFactory xif = XMLInputFactory.newInstance();
+        xif.setProperty(XMLInputFactory.IS_SUPPORTING_EXTERNAL_ENTITIES, false);
+        xif.setProperty(XMLInputFactory.SUPPORT_DTD, false);
+        return xif;
+    }
 }
index cb8cfa531a10a6224ffe1b21ea64128d30ab2798..bd0e80c63f179e24ee160413717b1a46a6627080 100644 (file)
@@ -41,6 +41,7 @@ public class XMLResponseProcessor {
 
     public void handleMessage(String msg) throws SAXException, IOException {
         XMLReader reader = XMLReaderFactory.createXMLReader();
+        reader.setFeature("http://apache.org/xml/features/disallow-doctype-decl", true);
         reader.setContentHandler(new XMLResponseHandler(handler, stateSwitchingMap));
         reader.parse(new InputSource(new StringReader(msg)));
     }
index 2910e2535489a52bb4c4e81b9f2f57373ae4da56..dbee97969c73e05d0fc2ac1885d7255629d79379 100644 (file)
@@ -309,6 +309,8 @@ public class DenonMarantzHttpConnector extends DenonMarantzConnector {
             if (StringUtils.isNotBlank(result)) {
                 JAXBContext jc = JAXBContext.newInstance(response);
                 XMLInputFactory xif = XMLInputFactory.newInstance();
+                xif.setProperty(XMLInputFactory.IS_SUPPORTING_EXTERNAL_ENTITIES, false);
+                xif.setProperty(XMLInputFactory.SUPPORT_DTD, false);
                 XMLStreamReader xsr = xif.createXMLStreamReader(IOUtils.toInputStream(result));
                 xsr = new PropertyRenamerDelegate(xsr);
 
index 08fa52989bc3dee1e40ffa659d31ed92635475a1..614bf55ca41b5f35b0a0659526d29a02ce78e199 100644 (file)
@@ -261,8 +261,15 @@ public class DenonMarantzHandler extends BaseThingHandler implements DenonMarant
 
                 if (status == HttpURLConnection.HTTP_OK && response != null) {
                     DocumentBuilderFactory domFactory = DocumentBuilderFactory.newInstance();
-                    DocumentBuilder builder;
                     try {
+                        // see
+                        // https://cheatsheetseries.owasp.org/cheatsheets/XML_External_Entity_Prevention_Cheat_Sheet.html
+                        domFactory.setFeature("http://xml.org/sax/features/external-general-entities", false);
+                        domFactory.setFeature("http://xml.org/sax/features/external-parameter-entities", false);
+                        domFactory.setFeature("http://apache.org/xml/features/nonvalidating/load-external-dtd", false);
+                        domFactory.setXIncludeAware(false);
+                        domFactory.setExpandEntityReferences(false);
+                        DocumentBuilder builder;
                         builder = domFactory.newDocumentBuilder();
                         Document dDoc = builder.parse(new InputSource(new StringReader(response.getContentAsString())));
                         XPath xPath = XPathFactory.newInstance().newXPath();
index c31265f77de605cbb727fa9555257429bd3bfb6c..f18a1dbced342e4e046f337a7e4ea358263a83c9 100644 (file)
@@ -155,7 +155,14 @@ public abstract class DLinkHNAPCommunication {
             uri = new URI("http://" + ipAddress + "/HNAP1");
             httpClient.start();
 
-            parser = DocumentBuilderFactory.newInstance().newDocumentBuilder();
+            DocumentBuilderFactory dbf = DocumentBuilderFactory.newInstance();
+            // see https://cheatsheetseries.owasp.org/cheatsheets/XML_External_Entity_Prevention_Cheat_Sheet.html
+            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);
+            dbf.setXIncludeAware(false);
+            dbf.setExpandEntityReferences(false);
+            parser = dbf.newDocumentBuilder();
 
             final MessageFactory messageFactory = MessageFactory.newInstance();
             requestAction = messageFactory.createMessage();
index 01ca88f446ac9d1d830f4b0cfb2625bcdd74bd77..833e87eac1b9b92a48d96be19819e673f06bbe67 100644 (file)
@@ -81,9 +81,16 @@ public class Enigma2Client {
     private final Enigma2HttpClient enigma2HttpClient;
     private final DocumentBuilderFactory factory;
 
-    public Enigma2Client(String host, @Nullable String user, @Nullable String password, int requestTimeout) {
-        this.enigma2HttpClient = new Enigma2HttpClient(requestTimeout);
-        this.factory = DocumentBuilderFactory.newInstance();
+    public Enigma2Client(String host, @Nullable String user, @Nullable String password, int requestTimeout)
+            throws ParserConfigurationException {
+        enigma2HttpClient = new Enigma2HttpClient(requestTimeout);
+        factory = DocumentBuilderFactory.newInstance();
+        // see https://cheatsheetseries.owasp.org/cheatsheets/XML_External_Entity_Prevention_Cheat_Sheet.html
+        factory.setFeature("http://xml.org/sax/features/external-general-entities", false);
+        factory.setFeature("http://xml.org/sax/features/external-parameter-entities", false);
+        factory.setFeature("http://apache.org/xml/features/nonvalidating/load-external-dtd", false);
+        factory.setXIncludeAware(false);
+        factory.setExpandEntityReferences(false);
         if (StringUtils.isNotEmpty(user) && StringUtils.isNotEmpty(password)) {
             this.host = "http://" + user + ":" + password + "@" + host;
         } else {
index f3404266b6224ead28524d4a4727dc75bb564459..2e4e5a016b1d19f94c9f8d7f85a71471f805bb17 100644 (file)
@@ -105,6 +105,12 @@ public class Client {
     public Client() {
         documentBuilderFactory.setNamespaceAware(true);
         try {
+            // see https://cheatsheetseries.owasp.org/cheatsheets/XML_External_Entity_Prevention_Cheat_Sheet.html
+            documentBuilderFactory.setFeature("http://xml.org/sax/features/external-general-entities", false);
+            documentBuilderFactory.setFeature("http://xml.org/sax/features/external-parameter-entities", false);
+            documentBuilderFactory.setFeature("http://apache.org/xml/features/nonvalidating/load-external-dtd", false);
+            documentBuilderFactory.setXIncludeAware(false);
+            documentBuilderFactory.setExpandEntityReferences(false);
             documentBuilder = documentBuilderFactory.newDocumentBuilder();
         } catch (ParserConfigurationException e) {
             throw new IllegalStateException(e);
index 6f80ad5774e49639d390d846ebe28891867a9781..7b023743f31bbcd32c9b4b3f632301d1864311fe 100644 (file)
@@ -209,6 +209,12 @@ public class FrontierSiliconRadioApiResult {
     private Document getXmlDocFromString(String xmlString)
             throws ParserConfigurationException, SAXException, IOException {
         final DocumentBuilderFactory factory = DocumentBuilderFactory.newInstance();
+        // see https://cheatsheetseries.owasp.org/cheatsheets/XML_External_Entity_Prevention_Cheat_Sheet.html
+        factory.setFeature("http://xml.org/sax/features/external-general-entities", false);
+        factory.setFeature("http://xml.org/sax/features/external-parameter-entities", false);
+        factory.setFeature("http://apache.org/xml/features/nonvalidating/load-external-dtd", false);
+        factory.setXIncludeAware(false);
+        factory.setExpandEntityReferences(false);
         final DocumentBuilder builder = factory.newDocumentBuilder();
         final Document xmlDocument = builder.parse(new InputSource(new StringReader(xmlString)));
         return xmlDocument;
index 041b2157f1d2b5aadeca1eca361e837a7b9539c9..5007119ec66c8cfa6234fcbce021825d4e66c983 100644 (file)
@@ -61,7 +61,14 @@ public class StatusFileInterpreter {
 
     public void read() {
         try {
-            DocumentBuilder builder = DocumentBuilderFactory.newInstance().newDocumentBuilder();
+            DocumentBuilderFactory factory = DocumentBuilderFactory.newInstance();
+            // see https://cheatsheetseries.owasp.org/cheatsheets/XML_External_Entity_Prevention_Cheat_Sheet.html
+            factory.setFeature("http://xml.org/sax/features/external-general-entities", false);
+            factory.setFeature("http://xml.org/sax/features/external-parameter-entities", false);
+            factory.setFeature("http://apache.org/xml/features/nonvalidating/load-external-dtd", false);
+            factory.setXIncludeAware(false);
+            factory.setExpandEntityReferences(false);
+            DocumentBuilder builder = factory.newDocumentBuilder();
             String statusPage = HttpUtil.executeUrl("GET", String.format(URL_TEMPLATE, hostname), 5000);
             InputStream inputStream = new ByteArrayInputStream(statusPage.getBytes());
             Document document = builder.parse(inputStream);
index e2e3006fd1b307b2c74b3c56dced59f514816bd6..19bef988706d6ef97fccda86de9be443dc1a830f 100644 (file)
@@ -47,6 +47,9 @@ public class XmlRpcResponse implements RpcResponse {
             throws SAXException, ParserConfigurationException, IOException {
         SAXParserFactory factory = SAXParserFactory.newInstance();
         SAXParser saxParser = factory.newSAXParser();
+        factory.setFeature("https://xml.org/sax/features/external-general-entities", false);
+        saxParser.getXMLReader().setFeature("https://xml.org/sax/features/external-general-entities", false);
+        factory.setFeature("https://apache.org/xml/features/disallow-doctype-decl", true);
         InputSource inputSource = new InputSource(is);
         inputSource.setEncoding(encoding);
         saxParser.parse(inputSource, new XmlRpcHandler());
index 5ae74e779fb030cc7a11a1910fa3f4fe7848782f..9e88446733754352f60ad959c6d70f09fe5806aa 100644 (file)
@@ -50,7 +50,7 @@ public class HPWebServerClient {
 
     /**
      * Creates a new HP Web Server Client object.
-     * 
+     *
      * @param httpClient {HttpClient} The HttpClient to use for HTTP requests.
      * @param address The address for the Embedded Web Server.
      */
@@ -63,7 +63,7 @@ public class HPWebServerClient {
 
     /**
      * Gets the Status information from the Embedded Web Server.
-     * 
+     *
      * @return The status information.
      */
     public HPServerResult<HPStatus> getStatus() {
@@ -84,7 +84,7 @@ public class HPWebServerClient {
 
     /**
      * Gets the Usage information from the Embedded Web Server.
-     * 
+     *
      * @return The usage information.
      */
     public HPServerResult<HPUsage> getUsage() {
@@ -120,6 +120,12 @@ public class HPWebServerClient {
 
     private synchronized Document getDocument(String contentAsString)
             throws ParserConfigurationException, SAXException, IOException {
+        // see https://cheatsheetseries.owasp.org/cheatsheets/XML_External_Entity_Prevention_Cheat_Sheet.html
+        factory.setFeature("http://xml.org/sax/features/external-general-entities", false);
+        factory.setFeature("http://xml.org/sax/features/external-parameter-entities", false);
+        factory.setFeature("http://apache.org/xml/features/nonvalidating/load-external-dtd", false);
+        factory.setXIncludeAware(false);
+        factory.setExpandEntityReferences(false);
         DocumentBuilder builder = factory.newDocumentBuilder();
         InputSource source = new InputSource(new StringReader(contentAsString));
         return builder.parse(source);
index 42ad09fc10e7cdccc7e9344e588e8763d87d6d56..38352b2424e5a657a600b612d067b5195125cf82 100644 (file)
@@ -53,6 +53,12 @@ public class ProjectFileUtils {
         File fXmlFile = new File(filePath);
         DocumentBuilderFactory dbFactory = DocumentBuilderFactory.newInstance();
         try {
+            // see https://cheatsheetseries.owasp.org/cheatsheets/XML_External_Entity_Prevention_Cheat_Sheet.html
+            dbFactory.setFeature("http://xml.org/sax/features/external-general-entities", false);
+            dbFactory.setFeature("http://xml.org/sax/features/external-parameter-entities", false);
+            dbFactory.setFeature("http://apache.org/xml/features/nonvalidating/load-external-dtd", false);
+            dbFactory.setXIncludeAware(false);
+            dbFactory.setExpandEntityReferences(false);
             DocumentBuilder dBuilder = dbFactory.newDocumentBuilder();
             Document doc = dBuilder.parse(fXmlFile);
             return doc;
index de1efc422e3583e2aa8948a76ac7119377fc861d..f4fe134bc2aae52216154f3e7f93f1253729a7c6 100644 (file)
@@ -78,6 +78,12 @@ public class DeviceTypeLoader {
      */
     public void loadDeviceTypesXML(InputStream in) throws ParserConfigurationException, SAXException, IOException {
         DocumentBuilderFactory dbFactory = DocumentBuilderFactory.newInstance();
+        // see https://cheatsheetseries.owasp.org/cheatsheets/XML_External_Entity_Prevention_Cheat_Sheet.html
+        dbFactory.setFeature("http://xml.org/sax/features/external-general-entities", false);
+        dbFactory.setFeature("http://xml.org/sax/features/external-parameter-entities", false);
+        dbFactory.setFeature("http://apache.org/xml/features/nonvalidating/load-external-dtd", false);
+        dbFactory.setXIncludeAware(false);
+        dbFactory.setExpandEntityReferences(false);
         DocumentBuilder dBuilder = dbFactory.newDocumentBuilder();
         Document doc = dBuilder.parse(in);
         doc.getDocumentElement().normalize();
index 4b43643bf23e4176284ded069e3d3746c4aac968..b297bfdb9d4c2b3cbe57972b0c98ae4b69c78078 100644 (file)
@@ -51,6 +51,12 @@ public class FeatureTemplateLoader {
         List<FeatureTemplate> features = new ArrayList<>();
         try {
             DocumentBuilderFactory dbFactory = DocumentBuilderFactory.newInstance();
+            // see https://cheatsheetseries.owasp.org/cheatsheets/XML_External_Entity_Prevention_Cheat_Sheet.html
+            dbFactory.setFeature("http://xml.org/sax/features/external-general-entities", false);
+            dbFactory.setFeature("http://xml.org/sax/features/external-parameter-entities", false);
+            dbFactory.setFeature("http://apache.org/xml/features/nonvalidating/load-external-dtd", false);
+            dbFactory.setXIncludeAware(false);
+            dbFactory.setExpandEntityReferences(false);
             DocumentBuilder dBuilder = dbFactory.newDocumentBuilder();
             // Parse it!
             Document doc = dBuilder.parse(input);
index 493b9a74c6dc6baabd38bb75a892ff6bcaa7d65e..4fb0aa4098b9c63727d2c3a18831b5ea4f657253 100644 (file)
@@ -55,6 +55,12 @@ public class XMLMessageReader {
         Map<String, Msg> messageMap = new HashMap<>();
         try {
             DocumentBuilderFactory dbFactory = DocumentBuilderFactory.newInstance();
+            // see https://cheatsheetseries.owasp.org/cheatsheets/XML_External_Entity_Prevention_Cheat_Sheet.html
+            dbFactory.setFeature("http://xml.org/sax/features/external-general-entities", false);
+            dbFactory.setFeature("http://xml.org/sax/features/external-parameter-entities", false);
+            dbFactory.setFeature("http://apache.org/xml/features/nonvalidating/load-external-dtd", false);
+            dbFactory.setXIncludeAware(false);
+            dbFactory.setExpandEntityReferences(false);
             DocumentBuilder dBuilder = dbFactory.newDocumentBuilder();
             // Parse it!
             Document doc = dBuilder.parse(input);
index 274a4c7e9d3baa5d5d2fa794815d56480a86443b..ab9f984b131e57c1d7ebf1175e3fea7f0fa16add 100644 (file)
@@ -498,6 +498,12 @@ public class OnkyoHandler extends UpnpAudioSinkHandler implements OnkyoEventList
     private void processInfo(String infoXML) {
         try {
             DocumentBuilderFactory factory = DocumentBuilderFactory.newInstance();
+            // see https://cheatsheetseries.owasp.org/cheatsheets/XML_External_Entity_Prevention_Cheat_Sheet.html
+            factory.setFeature("http://xml.org/sax/features/external-general-entities", false);
+            factory.setFeature("http://xml.org/sax/features/external-parameter-entities", false);
+            factory.setFeature("http://apache.org/xml/features/nonvalidating/load-external-dtd", false);
+            factory.setXIncludeAware(false);
+            factory.setExpandEntityReferences(false);
             DocumentBuilder builder = factory.newDocumentBuilder();
             try (StringReader sr = new StringReader(infoXML)) {
                 InputSource is = new InputSource(sr);
index 1fee1bf347dbf4746d9bb32c957897774ee4dae5..57596177a6856ee2d6b6083da2a5ea0d753d1413 100644 (file)
@@ -14,6 +14,7 @@ package org.openhab.binding.roku.internal.communication;
 
 import javax.xml.bind.JAXBContext;
 import javax.xml.bind.JAXBException;
+import javax.xml.stream.XMLInputFactory;
 
 import org.eclipse.jdt.annotation.NonNullByDefault;
 import org.eclipse.jdt.annotation.Nullable;
@@ -38,6 +39,7 @@ public class JAXBUtils {
     public static final @Nullable JAXBContext JAXBCONTEXT_APPS = initJAXBContextApps();
     public static final @Nullable JAXBContext JAXBCONTEXT_DEVICE_INFO = initJAXBContextDeviceInfo();
     public static final @Nullable JAXBContext JAXBCONTEXT_PLAYER = initJAXBContextPlayer();
+    public static final XMLInputFactory XMLINPUTFACTORY = initXMLInputFactory();
 
     private static @Nullable JAXBContext initJAXBContextActiveApp() {
         try {
@@ -74,4 +76,11 @@ public class JAXBUtils {
             return null;
         }
     }
+
+    private static XMLInputFactory initXMLInputFactory() {
+        XMLInputFactory xif = XMLInputFactory.newInstance();
+        xif.setProperty(XMLInputFactory.IS_SUPPORTING_EXTERNAL_ENTITIES, false);
+        xif.setProperty(XMLInputFactory.SUPPORT_DTD, false);
+        return xif;
+    }
 }
index 1c9eeb541d3c71891e0dc71ddae9b10fac1b6f3c..6dfb0a1bfc49c70e388851a566fe127b92945b97 100644 (file)
@@ -20,6 +20,8 @@ import java.util.concurrent.TimeoutException;
 import javax.xml.bind.JAXBContext;
 import javax.xml.bind.JAXBException;
 import javax.xml.bind.Unmarshaller;
+import javax.xml.stream.XMLStreamException;
+import javax.xml.stream.XMLStreamReader;
 
 import org.eclipse.jdt.annotation.NonNullByDefault;
 import org.eclipse.jetty.client.HttpClient;
@@ -94,14 +96,16 @@ public class RokuCommunicator {
             if (ctx != null) {
                 Unmarshaller unmarshaller = ctx.createUnmarshaller();
                 if (unmarshaller != null) {
-                    DeviceInfo device = (DeviceInfo) unmarshaller.unmarshal(new StringReader(getCommand(urlQryDevice)));
+                    XMLStreamReader xsr = JAXBUtils.XMLINPUTFACTORY
+                            .createXMLStreamReader(new StringReader(getCommand(urlQryDevice)));
+                    DeviceInfo device = (DeviceInfo) unmarshaller.unmarshal(xsr);
                     if (device != null) {
                         return device;
                     }
                 }
             }
             throw new RokuHttpException("No DeviceInfo model in response");
-        } catch (JAXBException e) {
+        } catch (JAXBException | XMLStreamException e) {
             throw new RokuHttpException("Exception creating DeviceInfo Unmarshaller: " + e.getLocalizedMessage());
         }
     }
@@ -118,8 +122,10 @@ public class RokuCommunicator {
             if (ctx != null) {
                 Unmarshaller unmarshaller = ctx.createUnmarshaller();
                 if (unmarshaller != null) {
+                    XMLStreamReader xsr = JAXBUtils.XMLINPUTFACTORY
+                            .createXMLStreamReader(new StringReader(getCommand(urlQryActiveApp)));
                     ActiveApp activeApp = (ActiveApp) unmarshaller
-                            .unmarshal(new StringReader(getCommand(urlQryActiveApp)));
+                            .unmarshal(xsr));
                     if (activeApp != null) {
                         return activeApp;
                     }
@@ -143,14 +149,16 @@ public class RokuCommunicator {
             if (ctx != null) {
                 Unmarshaller unmarshaller = ctx.createUnmarshaller();
                 if (unmarshaller != null) {
-                    Apps appList = (Apps) unmarshaller.unmarshal(new StringReader(getCommand(urlQryApps)));
+                    XMLStreamReader xsr = JAXBUtils.XMLINPUTFACTORY
+                            .createXMLStreamReader(new StringReader(getCommand(urlQryApps)));
+                    Apps appList = (Apps) unmarshaller.unmarshal(xsr);
                     if (appList != null) {
                         return appList.getApp();
                     }
                 }
             }
             throw new RokuHttpException("No AppList model in response");
-        } catch (JAXBException e) {
+        } catch (JAXBException | XMLStreamException e) {
             throw new RokuHttpException("Exception creating AppList Unmarshaller: " + e.getLocalizedMessage());
         }
     }
@@ -167,14 +175,16 @@ public class RokuCommunicator {
             if (ctx != null) {
                 Unmarshaller unmarshaller = ctx.createUnmarshaller();
                 if (unmarshaller != null) {
-                    Player playerInfo = (Player) unmarshaller.unmarshal(new StringReader(getCommand(urlQryPlayer)));
+                    XMLStreamReader xsr = JAXBUtils.XMLINPUTFACTORY
+                            .createXMLStreamReader(new StringReader(getCommand(urlQryPlayer)));
+                    Player playerInfo = (Player) unmarshaller.unmarshal(xsr);
                     if (playerInfo != null) {
                         return playerInfo;
                     }
                 }
             }
             throw new RokuHttpException("No Player info model in response");
-        } catch (JAXBException e) {
+        } catch (JAXBException | XMLStreamException e) {
             throw new RokuHttpException("Exception creating Player info Unmarshaller: " + e.getLocalizedMessage());
         }
     }
index d997f43f199c7151ef0e8ce302862c01b4611430..6c4be0ce934727ab28600c2d6a24b632fbb41dd7 100644 (file)
@@ -81,6 +81,12 @@ public class SamsungTvUtils {
     public static @Nullable Document loadXMLFromString(String xml) {
         try {
             DocumentBuilderFactory factory = DocumentBuilderFactory.newInstance();
+            // see https://cheatsheetseries.owasp.org/cheatsheets/XML_External_Entity_Prevention_Cheat_Sheet.html
+            factory.setFeature("http://xml.org/sax/features/external-general-entities", false);
+            factory.setFeature("http://xml.org/sax/features/external-parameter-entities", false);
+            factory.setFeature("http://apache.org/xml/features/nonvalidating/load-external-dtd", false);
+            factory.setXIncludeAware(false);
+            factory.setExpandEntityReferences(false);
             DocumentBuilder builder = factory.newDocumentBuilder();
             InputSource is = new InputSource(new StringReader(xml));
             return builder.parse(is);
index 85d3b8e7c159a06543d5600bbdacea0ca32659c6..1d53b7ce26d77d078fb5729f1de07dd208f34aa2 100644 (file)
@@ -134,6 +134,7 @@ public class SonosXMLParser {
      */
     public static @Nullable SonosResourceMetaData getResourceMetaData(String xml) throws SAXException {
         XMLReader reader = XMLReaderFactory.createXMLReader();
+        reader.setFeature("http://apache.org/xml/features/disallow-doctype-decl", true);
         ResourceMetaDataHandler handler = new ResourceMetaDataHandler();
         reader.setContentHandler(handler);
         try {
index 10663ddce21e98053da5e5f38de4db668fd3e387..ecdd033d507cd0acf34ca46bc7e23b2f59913b5b 100644 (file)
@@ -309,6 +309,8 @@ public class TelldusLiveDeviceController implements DeviceChangeListener, Sensor
         // TelldusLiveHandler.logger.info("Devices" + resp.getResponseBody());
         JAXBContext jc = JAXBContext.newInstance(response);
         XMLInputFactory xif = XMLInputFactory.newInstance();
+        xif.setProperty(XMLInputFactory.IS_SUPPORTING_EXTERNAL_ENTITIES, false);
+        xif.setProperty(XMLInputFactory.SUPPORT_DTD, false);
         XMLStreamReader xsr = xif.createXMLStreamReader(resp.getResponseBodyAsStream());
         // xsr = new PropertyRenamerDelegate(xsr);
 
index 8e7782b7636858e1ecb02cc810892e184cd8f477..44a2b60dc0ad75c6be43c5b418d586b7a8787197 100644 (file)
@@ -25,6 +25,9 @@ import java.util.stream.Collectors;
 import javax.xml.bind.JAXBContext;
 import javax.xml.bind.JAXBException;
 import javax.xml.bind.Unmarshaller;
+import javax.xml.stream.XMLInputFactory;
+import javax.xml.stream.XMLStreamException;
+import javax.xml.stream.XMLStreamReader;
 import javax.xml.transform.stream.StreamSource;
 
 import org.eclipse.jdt.annotation.NonNullByDefault;
@@ -64,8 +67,12 @@ public class Tr064PhonebookImpl implements Phonebook {
             InputStream xml = new ByteArrayInputStream(contentResponse.getContent());
 
             JAXBContext context = JAXBContext.newInstance(PhonebooksType.class);
+            XMLInputFactory xif = XMLInputFactory.newFactory();
+            xif.setProperty(XMLInputFactory.IS_SUPPORTING_EXTERNAL_ENTITIES, false);
+            xif.setProperty(XMLInputFactory.SUPPORT_DTD, false);
+            XMLStreamReader xsr = xif.createXMLStreamReader(new StreamSource(xml));
             Unmarshaller um = context.createUnmarshaller();
-            PhonebooksType phonebooksType = um.unmarshal(new StreamSource(xml), PhonebooksType.class).getValue();
+            PhonebooksType phonebooksType = um.unmarshal(xsr, PhonebooksType.class).getValue();
 
             phonebookName = phonebooksType.getPhonebook().getName();
 
@@ -76,7 +83,7 @@ public class Tr064PhonebookImpl implements Phonebook {
                                 this::mergeSameContactNames));
             }).collect(HashMap::new, HashMap::putAll, HashMap::putAll);
             logger.debug("Downloaded phonebook {}: {}", phonebookName, phonebook);
-        } catch (JAXBException | InterruptedException | ExecutionException | TimeoutException e) {
+        } catch (JAXBException | InterruptedException | ExecutionException | TimeoutException | XMLStreamException e) {
             logger.warn("Failed to get phonebook with URL {}:", phonebookUrl, e);
         }
     }
index 495e8cc846f932d498ebd63ab858b8266654635b..4655e5fedc2abcf42be38d9c23aca0a8e2fdd2a3 100644 (file)
@@ -18,7 +18,12 @@ import java.io.ByteArrayInputStream;
 import java.io.InputStream;
 import java.lang.reflect.Field;
 import java.time.Duration;
-import java.util.*;
+import java.util.Collections;
+import java.util.HashSet;
+import java.util.List;
+import java.util.Map;
+import java.util.Optional;
+import java.util.Set;
 import java.util.concurrent.ExecutionException;
 import java.util.concurrent.TimeUnit;
 import java.util.concurrent.TimeoutException;
@@ -31,6 +36,9 @@ import javax.xml.bind.JAXBException;
 import javax.xml.bind.Unmarshaller;
 import javax.xml.soap.SOAPException;
 import javax.xml.soap.SOAPMessage;
+import javax.xml.stream.XMLInputFactory;
+import javax.xml.stream.XMLStreamException;
+import javax.xml.stream.XMLStreamReader;
 import javax.xml.transform.stream.StreamSource;
 
 import org.eclipse.jdt.annotation.NonNullByDefault;
@@ -49,7 +57,11 @@ import org.openhab.binding.tr064.internal.dto.config.ChannelTypeDescription;
 import org.openhab.binding.tr064.internal.dto.config.ChannelTypeDescriptions;
 import org.openhab.binding.tr064.internal.dto.config.ParameterType;
 import org.openhab.binding.tr064.internal.dto.scpd.root.SCPDServiceType;
-import org.openhab.binding.tr064.internal.dto.scpd.service.*;
+import org.openhab.binding.tr064.internal.dto.scpd.service.SCPDActionType;
+import org.openhab.binding.tr064.internal.dto.scpd.service.SCPDArgumentType;
+import org.openhab.binding.tr064.internal.dto.scpd.service.SCPDDirection;
+import org.openhab.binding.tr064.internal.dto.scpd.service.SCPDScpdType;
+import org.openhab.binding.tr064.internal.dto.scpd.service.SCPDStateVariableType;
 import org.openhab.core.cache.ExpiringCacheMap;
 import org.openhab.core.thing.ChannelUID;
 import org.openhab.core.thing.Thing;
@@ -76,18 +88,21 @@ public class Util {
 
     /**
      * read the channel config from the resource file (static initialization)
-     * 
+     *
      * @return a list of all available channel configurations
      */
     public static List<ChannelTypeDescription> readXMLChannelConfig() {
         try {
             InputStream resource = Thread.currentThread().getContextClassLoader().getResourceAsStream("channels.xml");
             JAXBContext context = JAXBContext.newInstance(ChannelTypeDescriptions.class);
+            XMLInputFactory xif = XMLInputFactory.newFactory();
+            xif.setProperty(XMLInputFactory.IS_SUPPORTING_EXTERNAL_ENTITIES, false);
+            xif.setProperty(XMLInputFactory.SUPPORT_DTD, false);
+            XMLStreamReader xsr = xif.createXMLStreamReader(new StreamSource(resource));
             Unmarshaller um = context.createUnmarshaller();
-            JAXBElement<ChannelTypeDescriptions> root = um.unmarshal(new StreamSource(resource),
-                    ChannelTypeDescriptions.class);
+            JAXBElement<ChannelTypeDescriptions> root = um.unmarshal(xsr, ChannelTypeDescriptions.class);
             return root.getValue().getChannel();
-        } catch (JAXBException e) {
+        } catch (JAXBException | XMLStreamException e) {
             LOGGER.warn("Failed to read channel definitions", e);
             return List.of();
         }
@@ -95,7 +110,7 @@ public class Util {
 
     /**
      * Extract an argument from an SCPD action definition
-     * 
+     *
      * @param scpdAction the action object
      * @param argumentName the argument's name
      * @param direction the direction (in or out)
@@ -114,7 +129,7 @@ public class Util {
 
     /**
      * Extract the related state variable from the service root for a given argument
-     * 
+     *
      * @param serviceRoot the service root object
      * @param scpdArgument the argument object
      * @return the related state variable object for this argument
@@ -130,7 +145,7 @@ public class Util {
 
     /**
      * Extract an action from the service root
-     * 
+     *
      * @param serviceRoot the service root object
      * @param actionName the action name
      * @param actionType "Get-Action" or "Set-Action" (for exception string only)
@@ -338,14 +353,18 @@ public class Util {
                     InputStream xml = new ByteArrayInputStream(response);
 
                     JAXBContext context = JAXBContext.newInstance(clazz);
+                    XMLInputFactory xif = XMLInputFactory.newFactory();
+                    xif.setProperty(XMLInputFactory.IS_SUPPORTING_EXTERNAL_ENTITIES, false);
+                    xif.setProperty(XMLInputFactory.SUPPORT_DTD, false);
+                    XMLStreamReader xsr = xif.createXMLStreamReader(new StreamSource(xml));
                     Unmarshaller um = context.createUnmarshaller();
-                    T newValue = um.unmarshal(new StreamSource(xml), clazz).getValue();
+                    T newValue = um.unmarshal(xsr, clazz).getValue();
                     LOGGER.trace("Storing in cache {}", newValue);
                     return newValue;
                 } catch (ExecutionException | InterruptedException | TimeoutException e) {
                     LOGGER.debug("HTTP Failed to GET uri '{}': {}", uri, e.getMessage());
                     throw new IllegalArgumentException();
-                } catch (JAXBException e) {
+                } catch (JAXBException | XMLStreamException e) {
                     LOGGER.debug("Unmarshalling failed: {}", e.getMessage());
                     throw new IllegalArgumentException();
                 }
index 2fa703dfb058367992e6c20a90d1ab4f12a9ecfc..7fd1d7d622816bbeb2fe6359010766d798c7ad46 100644 (file)
@@ -79,6 +79,9 @@ public class UpnpXMLParser {
         try {
             SAXParserFactory factory = SAXParserFactory.newInstance();
             SAXParser saxParser = factory.newSAXParser();
+            factory.setFeature("https://xml.org/sax/features/external-general-entities", false);
+            saxParser.getXMLReader().setFeature("https://xml.org/sax/features/external-general-entities", false);
+            factory.setFeature("https://apache.org/xml/features/disallow-doctype-decl", true);
             saxParser.parse(new InputSource(new StringReader(xml)), handler);
         } catch (IOException e) {
             // This should never happen - we're not performing I/O!
@@ -135,6 +138,9 @@ public class UpnpXMLParser {
         try {
             SAXParserFactory factory = SAXParserFactory.newInstance();
             SAXParser saxParser = factory.newSAXParser();
+            factory.setFeature("https://xml.org/sax/features/external-general-entities", false);
+            saxParser.getXMLReader().setFeature("https://xml.org/sax/features/external-general-entities", false);
+            factory.setFeature("https://apache.org/xml/features/disallow-doctype-decl", true);
             saxParser.parse(new InputSource(new StringReader(xml)), handler);
         } catch (IOException e) {
             // This should never happen - we're not performing I/O!
@@ -179,6 +185,9 @@ public class UpnpXMLParser {
         try {
             SAXParserFactory factory = SAXParserFactory.newInstance();
             SAXParser saxParser = factory.newSAXParser();
+            factory.setFeature("https://xml.org/sax/features/external-general-entities", false);
+            saxParser.getXMLReader().setFeature("https://xml.org/sax/features/external-general-entities", false);
+            factory.setFeature("https://apache.org/xml/features/disallow-doctype-decl", true);
             saxParser.parse(new InputSource(new StringReader(xml)), handler);
         } catch (IOException e) {
             // This should never happen - we're not performing I/O!
index e5132e894b9d28a1d8d751597d3164d495536c6f..a08643af6c91e7f7bac131a572e825e93bbd3fa0 100644 (file)
@@ -250,6 +250,7 @@ public class VitotronicBridgeHandler extends BaseBridgeHandler {
         logger.trace("Start Background Thread for recieving data from adapter");
         try {
             XMLReader xmlReader = XMLReaderFactory.createXMLReader();
+            xmlReader.setFeature("http://apache.org/xml/features/disallow-doctype-decl", true);
             xmlReader.setContentHandler(new XmlHandler());
             logger.trace("Start Parser for optolink adapter");
             xmlReader.parse(new InputSource(inStream));
index 657fd815e703d113f726c0b50ee08922984e97e1..535661bb1a2b967958f122b15e3b39ff7c5108a1 100644 (file)
@@ -156,6 +156,13 @@ public class WemoLinkDiscoveryService extends AbstractDiscoveryService implement
 
                         // Build parser for received <DeviceList>
                         DocumentBuilderFactory dbf = DocumentBuilderFactory.newInstance();
+                        // see
+                        // https://cheatsheetseries.owasp.org/cheatsheets/XML_External_Entity_Prevention_Cheat_Sheet.html
+                        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);
+                        dbf.setXIncludeAware(false);
+                        dbf.setExpandEntityReferences(false);
                         DocumentBuilder db = dbf.newDocumentBuilder();
                         InputSource is = new InputSource();
                         is.setCharacterStream(new StringReader(stringParser));
index 2289b989e6815c7639f546a51e8df4e532a523c9..1e000d8dbe29f971e284030ee596199d60ccf510 100644 (file)
@@ -290,6 +290,13 @@ public class WemoCoffeeHandler extends AbstractWemoHandler implements UpnpIOPart
                         stringParser = "<data>" + stringParser + "</data>";
 
                         DocumentBuilderFactory dbf = DocumentBuilderFactory.newInstance();
+                        // see
+                        // https://cheatsheetseries.owasp.org/cheatsheets/XML_External_Entity_Prevention_Cheat_Sheet.html
+                        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);
+                        dbf.setXIncludeAware(false);
+                        dbf.setExpandEntityReferences(false);
                         DocumentBuilder db = dbf.newDocumentBuilder();
                         InputSource is = new InputSource();
                         is.setCharacterStream(new StringReader(stringParser));
index aaf3fe168a0d390d043bded286790a64db5cdfb0..4ef7c2ebcdc59ba062c100dea18bb6d1b9d31b8f 100644 (file)
@@ -359,6 +359,13 @@ public class WemoHolmesHandler extends AbstractWemoHandler implements UpnpIOPart
                     stringParser = "<data>" + stringParser + "</data>";
 
                     DocumentBuilderFactory dbf = DocumentBuilderFactory.newInstance();
+                    // see
+                    // https://cheatsheetseries.owasp.org/cheatsheets/XML_External_Entity_Prevention_Cheat_Sheet.html
+                    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);
+                    dbf.setXIncludeAware(false);
+                    dbf.setExpandEntityReferences(false);
                     DocumentBuilder db = dbf.newDocumentBuilder();
                     InputSource is = new InputSource();
                     is.setCharacterStream(new StringReader(stringParser));
index 97ecfc36209b12293dd0edd9478b7e62cb280a9e..03cdbcd95600533e79c0f5b6a12c86ca6d78b092 100644 (file)
@@ -222,6 +222,13 @@ public class WemoMakerHandler extends AbstractWemoHandler implements UpnpIOParti
                         stringParser = "<data>" + stringParser + "</data>";
 
                         DocumentBuilderFactory dbf = DocumentBuilderFactory.newInstance();
+                        // see
+                        // https://cheatsheetseries.owasp.org/cheatsheets/XML_External_Entity_Prevention_Cheat_Sheet.html
+                        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);
+                        dbf.setXIncludeAware(false);
+                        dbf.setExpandEntityReferences(false);
                         DocumentBuilder db = dbf.newDocumentBuilder();
                         InputSource is = new InputSource();
                         is.setCharacterStream(new StringReader(stringParser));
index 402d55a36237f5855b0cc64d430acbaf6a397e98..5356f6db0444cdb652bde00333aca419da59fa8b 100644 (file)
@@ -173,7 +173,13 @@ public class XMLUtils {
                 : "<?xml version=\"1.0\" encoding=\"utf-8\"?>" + message;
 
         try {
-            return XMLUtils.dbf.newDocumentBuilder().parse(new InputSource(new StringReader(response)));
+            // see https://cheatsheetseries.owasp.org/cheatsheets/XML_External_Entity_Prevention_Cheat_Sheet.html
+            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);
+            dbf.setXIncludeAware(false);
+            dbf.setExpandEntityReferences(false);
+            return dbf.newDocumentBuilder().parse(new InputSource(new StringReader(response)));
         } catch (SAXException | ParserConfigurationException e) {
             throw new ReceivedMessageParseException(e);
         }
index 2dc50a9343390b076e86f432bc020eab13890432..0464dacdc0431499892719089cea8ae597578540 100644 (file)
@@ -55,6 +55,12 @@ public class XPathTransformationService implements TransformationService {
 
         try {
             DocumentBuilderFactory domFactory = DocumentBuilderFactory.newInstance();
+            // see https://cheatsheetseries.owasp.org/cheatsheets/XML_External_Entity_Prevention_Cheat_Sheet.html
+            domFactory.setFeature("http://xml.org/sax/features/external-general-entities", false);
+            domFactory.setFeature("http://xml.org/sax/features/external-parameter-entities", false);
+            domFactory.setFeature("http://apache.org/xml/features/nonvalidating/load-external-dtd", false);
+            domFactory.setXIncludeAware(false);
+            domFactory.setExpandEntityReferences(false);
             domFactory.setNamespaceAware(true);
             domFactory.setValidating(false);
             DocumentBuilder builder = domFactory.newDocumentBuilder();