diff --git a/bundles/org.openhab.binding.avmfritz/src/main/java/org/openhab/binding/avmfritz/internal/hardware/callbacks/FritzAhaUpdateCallback.java b/bundles/org.openhab.binding.avmfritz/src/main/java/org/openhab/binding/avmfritz/internal/hardware/callbacks/FritzAhaUpdateCallback.java index 16bacbce5..31caca094 100644 --- a/bundles/org.openhab.binding.avmfritz/src/main/java/org/openhab/binding/avmfritz/internal/hardware/callbacks/FritzAhaUpdateCallback.java +++ b/bundles/org.openhab.binding.avmfritz/src/main/java/org/openhab/binding/avmfritz/internal/hardware/callbacks/FritzAhaUpdateCallback.java @@ -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()); diff --git a/bundles/org.openhab.binding.avmfritz/src/main/java/org/openhab/binding/avmfritz/internal/hardware/callbacks/FritzAhaUpdateTemplatesCallback.java b/bundles/org.openhab.binding.avmfritz/src/main/java/org/openhab/binding/avmfritz/internal/hardware/callbacks/FritzAhaUpdateTemplatesCallback.java index c3a47a033..d976c3b35 100644 --- a/bundles/org.openhab.binding.avmfritz/src/main/java/org/openhab/binding/avmfritz/internal/hardware/callbacks/FritzAhaUpdateTemplatesCallback.java +++ b/bundles/org.openhab.binding.avmfritz/src/main/java/org/openhab/binding/avmfritz/internal/hardware/callbacks/FritzAhaUpdateTemplatesCallback.java @@ -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 { diff --git a/bundles/org.openhab.binding.avmfritz/src/main/java/org/openhab/binding/avmfritz/internal/util/JAXBUtils.java b/bundles/org.openhab.binding.avmfritz/src/main/java/org/openhab/binding/avmfritz/internal/util/JAXBUtils.java index 55d454f5b..742745396 100644 --- a/bundles/org.openhab.binding.avmfritz/src/main/java/org/openhab/binding/avmfritz/internal/util/JAXBUtils.java +++ b/bundles/org.openhab.binding.avmfritz/src/main/java/org/openhab/binding/avmfritz/internal/util/JAXBUtils.java @@ -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; + } } diff --git a/bundles/org.openhab.binding.bosesoundtouch/src/main/java/org/openhab/binding/bosesoundtouch/internal/XMLResponseProcessor.java b/bundles/org.openhab.binding.bosesoundtouch/src/main/java/org/openhab/binding/bosesoundtouch/internal/XMLResponseProcessor.java index cb8cfa531..bd0e80c63 100644 --- a/bundles/org.openhab.binding.bosesoundtouch/src/main/java/org/openhab/binding/bosesoundtouch/internal/XMLResponseProcessor.java +++ b/bundles/org.openhab.binding.bosesoundtouch/src/main/java/org/openhab/binding/bosesoundtouch/internal/XMLResponseProcessor.java @@ -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))); } diff --git a/bundles/org.openhab.binding.denonmarantz/src/main/java/org/openhab/binding/denonmarantz/internal/connector/http/DenonMarantzHttpConnector.java b/bundles/org.openhab.binding.denonmarantz/src/main/java/org/openhab/binding/denonmarantz/internal/connector/http/DenonMarantzHttpConnector.java index 2910e2535..dbee97969 100644 --- a/bundles/org.openhab.binding.denonmarantz/src/main/java/org/openhab/binding/denonmarantz/internal/connector/http/DenonMarantzHttpConnector.java +++ b/bundles/org.openhab.binding.denonmarantz/src/main/java/org/openhab/binding/denonmarantz/internal/connector/http/DenonMarantzHttpConnector.java @@ -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); diff --git a/bundles/org.openhab.binding.denonmarantz/src/main/java/org/openhab/binding/denonmarantz/internal/handler/DenonMarantzHandler.java b/bundles/org.openhab.binding.denonmarantz/src/main/java/org/openhab/binding/denonmarantz/internal/handler/DenonMarantzHandler.java index 08fa52989..614bf55ca 100644 --- a/bundles/org.openhab.binding.denonmarantz/src/main/java/org/openhab/binding/denonmarantz/internal/handler/DenonMarantzHandler.java +++ b/bundles/org.openhab.binding.denonmarantz/src/main/java/org/openhab/binding/denonmarantz/internal/handler/DenonMarantzHandler.java @@ -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(); diff --git a/bundles/org.openhab.binding.dlinksmarthome/src/main/java/org/openhab/binding/dlinksmarthome/internal/DLinkHNAPCommunication.java b/bundles/org.openhab.binding.dlinksmarthome/src/main/java/org/openhab/binding/dlinksmarthome/internal/DLinkHNAPCommunication.java index c31265f77..f18a1dbce 100644 --- a/bundles/org.openhab.binding.dlinksmarthome/src/main/java/org/openhab/binding/dlinksmarthome/internal/DLinkHNAPCommunication.java +++ b/bundles/org.openhab.binding.dlinksmarthome/src/main/java/org/openhab/binding/dlinksmarthome/internal/DLinkHNAPCommunication.java @@ -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(); diff --git a/bundles/org.openhab.binding.enigma2/src/main/java/org/openhab/binding/enigma2/internal/Enigma2Client.java b/bundles/org.openhab.binding.enigma2/src/main/java/org/openhab/binding/enigma2/internal/Enigma2Client.java index 01ca88f44..833e87eac 100644 --- a/bundles/org.openhab.binding.enigma2/src/main/java/org/openhab/binding/enigma2/internal/Enigma2Client.java +++ b/bundles/org.openhab.binding.enigma2/src/main/java/org/openhab/binding/enigma2/internal/Enigma2Client.java @@ -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 { diff --git a/bundles/org.openhab.binding.fmiweather/src/main/java/org/openhab/binding/fmiweather/internal/client/Client.java b/bundles/org.openhab.binding.fmiweather/src/main/java/org/openhab/binding/fmiweather/internal/client/Client.java index f3404266b..2e4e5a016 100644 --- a/bundles/org.openhab.binding.fmiweather/src/main/java/org/openhab/binding/fmiweather/internal/client/Client.java +++ b/bundles/org.openhab.binding.fmiweather/src/main/java/org/openhab/binding/fmiweather/internal/client/Client.java @@ -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); diff --git a/bundles/org.openhab.binding.fsinternetradio/src/main/java/org/openhab/binding/fsinternetradio/internal/radio/FrontierSiliconRadioApiResult.java b/bundles/org.openhab.binding.fsinternetradio/src/main/java/org/openhab/binding/fsinternetradio/internal/radio/FrontierSiliconRadioApiResult.java index 6f80ad577..7b023743f 100644 --- a/bundles/org.openhab.binding.fsinternetradio/src/main/java/org/openhab/binding/fsinternetradio/internal/radio/FrontierSiliconRadioApiResult.java +++ b/bundles/org.openhab.binding.fsinternetradio/src/main/java/org/openhab/binding/fsinternetradio/internal/radio/FrontierSiliconRadioApiResult.java @@ -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; diff --git a/bundles/org.openhab.binding.gce/src/main/java/org/openhab/binding/gce/internal/model/StatusFileInterpreter.java b/bundles/org.openhab.binding.gce/src/main/java/org/openhab/binding/gce/internal/model/StatusFileInterpreter.java index 041b2157f..5007119ec 100644 --- a/bundles/org.openhab.binding.gce/src/main/java/org/openhab/binding/gce/internal/model/StatusFileInterpreter.java +++ b/bundles/org.openhab.binding.gce/src/main/java/org/openhab/binding/gce/internal/model/StatusFileInterpreter.java @@ -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); diff --git a/bundles/org.openhab.binding.homematic/src/main/java/org/openhab/binding/homematic/internal/communicator/message/XmlRpcResponse.java b/bundles/org.openhab.binding.homematic/src/main/java/org/openhab/binding/homematic/internal/communicator/message/XmlRpcResponse.java index e2e3006fd..19bef9887 100644 --- a/bundles/org.openhab.binding.homematic/src/main/java/org/openhab/binding/homematic/internal/communicator/message/XmlRpcResponse.java +++ b/bundles/org.openhab.binding.homematic/src/main/java/org/openhab/binding/homematic/internal/communicator/message/XmlRpcResponse.java @@ -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()); diff --git a/bundles/org.openhab.binding.hpprinter/src/main/java/org/openhab/binding/hpprinter/internal/api/HPWebServerClient.java b/bundles/org.openhab.binding.hpprinter/src/main/java/org/openhab/binding/hpprinter/internal/api/HPWebServerClient.java index 5ae74e779..9e8844673 100644 --- a/bundles/org.openhab.binding.hpprinter/src/main/java/org/openhab/binding/hpprinter/internal/api/HPWebServerClient.java +++ b/bundles/org.openhab.binding.hpprinter/src/main/java/org/openhab/binding/hpprinter/internal/api/HPWebServerClient.java @@ -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 getStatus() { @@ -84,7 +84,7 @@ public class HPWebServerClient { /** * Gets the Usage information from the Embedded Web Server. - * + * * @return The usage information. */ public HPServerResult 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); diff --git a/bundles/org.openhab.binding.ihc/src/main/java/org/openhab/binding/ihc/internal/ws/projectfile/ProjectFileUtils.java b/bundles/org.openhab.binding.ihc/src/main/java/org/openhab/binding/ihc/internal/ws/projectfile/ProjectFileUtils.java index 42ad09fc1..38352b242 100644 --- a/bundles/org.openhab.binding.ihc/src/main/java/org/openhab/binding/ihc/internal/ws/projectfile/ProjectFileUtils.java +++ b/bundles/org.openhab.binding.ihc/src/main/java/org/openhab/binding/ihc/internal/ws/projectfile/ProjectFileUtils.java @@ -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; diff --git a/bundles/org.openhab.binding.insteon/src/main/java/org/openhab/binding/insteon/internal/device/DeviceTypeLoader.java b/bundles/org.openhab.binding.insteon/src/main/java/org/openhab/binding/insteon/internal/device/DeviceTypeLoader.java index de1efc422..f4fe134bc 100644 --- a/bundles/org.openhab.binding.insteon/src/main/java/org/openhab/binding/insteon/internal/device/DeviceTypeLoader.java +++ b/bundles/org.openhab.binding.insteon/src/main/java/org/openhab/binding/insteon/internal/device/DeviceTypeLoader.java @@ -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(); diff --git a/bundles/org.openhab.binding.insteon/src/main/java/org/openhab/binding/insteon/internal/device/FeatureTemplateLoader.java b/bundles/org.openhab.binding.insteon/src/main/java/org/openhab/binding/insteon/internal/device/FeatureTemplateLoader.java index 4b43643bf..b297bfdb9 100644 --- a/bundles/org.openhab.binding.insteon/src/main/java/org/openhab/binding/insteon/internal/device/FeatureTemplateLoader.java +++ b/bundles/org.openhab.binding.insteon/src/main/java/org/openhab/binding/insteon/internal/device/FeatureTemplateLoader.java @@ -51,6 +51,12 @@ public class FeatureTemplateLoader { List 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); diff --git a/bundles/org.openhab.binding.insteon/src/main/java/org/openhab/binding/insteon/internal/message/XMLMessageReader.java b/bundles/org.openhab.binding.insteon/src/main/java/org/openhab/binding/insteon/internal/message/XMLMessageReader.java index 493b9a74c..4fb0aa409 100644 --- a/bundles/org.openhab.binding.insteon/src/main/java/org/openhab/binding/insteon/internal/message/XMLMessageReader.java +++ b/bundles/org.openhab.binding.insteon/src/main/java/org/openhab/binding/insteon/internal/message/XMLMessageReader.java @@ -55,6 +55,12 @@ public class XMLMessageReader { Map 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); diff --git a/bundles/org.openhab.binding.onkyo/src/main/java/org/openhab/binding/onkyo/internal/handler/OnkyoHandler.java b/bundles/org.openhab.binding.onkyo/src/main/java/org/openhab/binding/onkyo/internal/handler/OnkyoHandler.java index 274a4c7e9..ab9f984b1 100644 --- a/bundles/org.openhab.binding.onkyo/src/main/java/org/openhab/binding/onkyo/internal/handler/OnkyoHandler.java +++ b/bundles/org.openhab.binding.onkyo/src/main/java/org/openhab/binding/onkyo/internal/handler/OnkyoHandler.java @@ -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); diff --git a/bundles/org.openhab.binding.roku/src/main/java/org/openhab/binding/roku/internal/communication/JAXBUtils.java b/bundles/org.openhab.binding.roku/src/main/java/org/openhab/binding/roku/internal/communication/JAXBUtils.java index 1fee1bf34..57596177a 100644 --- a/bundles/org.openhab.binding.roku/src/main/java/org/openhab/binding/roku/internal/communication/JAXBUtils.java +++ b/bundles/org.openhab.binding.roku/src/main/java/org/openhab/binding/roku/internal/communication/JAXBUtils.java @@ -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; + } } diff --git a/bundles/org.openhab.binding.roku/src/main/java/org/openhab/binding/roku/internal/communication/RokuCommunicator.java b/bundles/org.openhab.binding.roku/src/main/java/org/openhab/binding/roku/internal/communication/RokuCommunicator.java index 1c9eeb541..6dfb0a1bf 100644 --- a/bundles/org.openhab.binding.roku/src/main/java/org/openhab/binding/roku/internal/communication/RokuCommunicator.java +++ b/bundles/org.openhab.binding.roku/src/main/java/org/openhab/binding/roku/internal/communication/RokuCommunicator.java @@ -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()); } } diff --git a/bundles/org.openhab.binding.samsungtv/src/main/java/org/openhab/binding/samsungtv/internal/service/SamsungTvUtils.java b/bundles/org.openhab.binding.samsungtv/src/main/java/org/openhab/binding/samsungtv/internal/service/SamsungTvUtils.java index d997f43f1..6c4be0ce9 100644 --- a/bundles/org.openhab.binding.samsungtv/src/main/java/org/openhab/binding/samsungtv/internal/service/SamsungTvUtils.java +++ b/bundles/org.openhab.binding.samsungtv/src/main/java/org/openhab/binding/samsungtv/internal/service/SamsungTvUtils.java @@ -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); diff --git a/bundles/org.openhab.binding.sonos/src/main/java/org/openhab/binding/sonos/internal/SonosXMLParser.java b/bundles/org.openhab.binding.sonos/src/main/java/org/openhab/binding/sonos/internal/SonosXMLParser.java index 85d3b8e7c..1d53b7ce2 100644 --- a/bundles/org.openhab.binding.sonos/src/main/java/org/openhab/binding/sonos/internal/SonosXMLParser.java +++ b/bundles/org.openhab.binding.sonos/src/main/java/org/openhab/binding/sonos/internal/SonosXMLParser.java @@ -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 { diff --git a/bundles/org.openhab.binding.tellstick/src/main/java/org/openhab/binding/tellstick/internal/live/TelldusLiveDeviceController.java b/bundles/org.openhab.binding.tellstick/src/main/java/org/openhab/binding/tellstick/internal/live/TelldusLiveDeviceController.java index 10663ddce..ecdd033d5 100644 --- a/bundles/org.openhab.binding.tellstick/src/main/java/org/openhab/binding/tellstick/internal/live/TelldusLiveDeviceController.java +++ b/bundles/org.openhab.binding.tellstick/src/main/java/org/openhab/binding/tellstick/internal/live/TelldusLiveDeviceController.java @@ -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); diff --git a/bundles/org.openhab.binding.tr064/src/main/java/org/openhab/binding/tr064/internal/phonebook/Tr064PhonebookImpl.java b/bundles/org.openhab.binding.tr064/src/main/java/org/openhab/binding/tr064/internal/phonebook/Tr064PhonebookImpl.java index 8e7782b76..44a2b60dc 100644 --- a/bundles/org.openhab.binding.tr064/src/main/java/org/openhab/binding/tr064/internal/phonebook/Tr064PhonebookImpl.java +++ b/bundles/org.openhab.binding.tr064/src/main/java/org/openhab/binding/tr064/internal/phonebook/Tr064PhonebookImpl.java @@ -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); } } diff --git a/bundles/org.openhab.binding.tr064/src/main/java/org/openhab/binding/tr064/internal/util/Util.java b/bundles/org.openhab.binding.tr064/src/main/java/org/openhab/binding/tr064/internal/util/Util.java index 495e8cc84..4655e5fed 100644 --- a/bundles/org.openhab.binding.tr064/src/main/java/org/openhab/binding/tr064/internal/util/Util.java +++ b/bundles/org.openhab.binding.tr064/src/main/java/org/openhab/binding/tr064/internal/util/Util.java @@ -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 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 root = um.unmarshal(new StreamSource(resource), - ChannelTypeDescriptions.class); + JAXBElement 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(); } diff --git a/bundles/org.openhab.binding.upnpcontrol/src/main/java/org/openhab/binding/upnpcontrol/internal/util/UpnpXMLParser.java b/bundles/org.openhab.binding.upnpcontrol/src/main/java/org/openhab/binding/upnpcontrol/internal/util/UpnpXMLParser.java index 2fa703dfb..7fd1d7d62 100644 --- a/bundles/org.openhab.binding.upnpcontrol/src/main/java/org/openhab/binding/upnpcontrol/internal/util/UpnpXMLParser.java +++ b/bundles/org.openhab.binding.upnpcontrol/src/main/java/org/openhab/binding/upnpcontrol/internal/util/UpnpXMLParser.java @@ -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! diff --git a/bundles/org.openhab.binding.vitotronic/src/main/java/org/openhab/binding/vitotronic/internal/handler/VitotronicBridgeHandler.java b/bundles/org.openhab.binding.vitotronic/src/main/java/org/openhab/binding/vitotronic/internal/handler/VitotronicBridgeHandler.java index e5132e894..a08643af6 100644 --- a/bundles/org.openhab.binding.vitotronic/src/main/java/org/openhab/binding/vitotronic/internal/handler/VitotronicBridgeHandler.java +++ b/bundles/org.openhab.binding.vitotronic/src/main/java/org/openhab/binding/vitotronic/internal/handler/VitotronicBridgeHandler.java @@ -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)); diff --git a/bundles/org.openhab.binding.wemo/src/main/java/org/openhab/binding/wemo/internal/discovery/WemoLinkDiscoveryService.java b/bundles/org.openhab.binding.wemo/src/main/java/org/openhab/binding/wemo/internal/discovery/WemoLinkDiscoveryService.java index 657fd815e..535661bb1 100644 --- a/bundles/org.openhab.binding.wemo/src/main/java/org/openhab/binding/wemo/internal/discovery/WemoLinkDiscoveryService.java +++ b/bundles/org.openhab.binding.wemo/src/main/java/org/openhab/binding/wemo/internal/discovery/WemoLinkDiscoveryService.java @@ -156,6 +156,13 @@ public class WemoLinkDiscoveryService extends AbstractDiscoveryService implement // Build parser for received 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)); diff --git a/bundles/org.openhab.binding.wemo/src/main/java/org/openhab/binding/wemo/internal/handler/WemoCoffeeHandler.java b/bundles/org.openhab.binding.wemo/src/main/java/org/openhab/binding/wemo/internal/handler/WemoCoffeeHandler.java index 2289b989e..1e000d8db 100644 --- a/bundles/org.openhab.binding.wemo/src/main/java/org/openhab/binding/wemo/internal/handler/WemoCoffeeHandler.java +++ b/bundles/org.openhab.binding.wemo/src/main/java/org/openhab/binding/wemo/internal/handler/WemoCoffeeHandler.java @@ -290,6 +290,13 @@ public class WemoCoffeeHandler extends AbstractWemoHandler implements UpnpIOPart stringParser = "" + stringParser + ""; 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)); diff --git a/bundles/org.openhab.binding.wemo/src/main/java/org/openhab/binding/wemo/internal/handler/WemoHolmesHandler.java b/bundles/org.openhab.binding.wemo/src/main/java/org/openhab/binding/wemo/internal/handler/WemoHolmesHandler.java index aaf3fe168..4ef7c2ebc 100644 --- a/bundles/org.openhab.binding.wemo/src/main/java/org/openhab/binding/wemo/internal/handler/WemoHolmesHandler.java +++ b/bundles/org.openhab.binding.wemo/src/main/java/org/openhab/binding/wemo/internal/handler/WemoHolmesHandler.java @@ -359,6 +359,13 @@ public class WemoHolmesHandler extends AbstractWemoHandler implements UpnpIOPart stringParser = "" + stringParser + ""; 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)); diff --git a/bundles/org.openhab.binding.wemo/src/main/java/org/openhab/binding/wemo/internal/handler/WemoMakerHandler.java b/bundles/org.openhab.binding.wemo/src/main/java/org/openhab/binding/wemo/internal/handler/WemoMakerHandler.java index 97ecfc362..03cdbcd95 100644 --- a/bundles/org.openhab.binding.wemo/src/main/java/org/openhab/binding/wemo/internal/handler/WemoMakerHandler.java +++ b/bundles/org.openhab.binding.wemo/src/main/java/org/openhab/binding/wemo/internal/handler/WemoMakerHandler.java @@ -222,6 +222,13 @@ public class WemoMakerHandler extends AbstractWemoHandler implements UpnpIOParti stringParser = "" + stringParser + ""; 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)); diff --git a/bundles/org.openhab.binding.yamahareceiver/src/main/java/org/openhab/binding/yamahareceiver/internal/protocol/xml/XMLUtils.java b/bundles/org.openhab.binding.yamahareceiver/src/main/java/org/openhab/binding/yamahareceiver/internal/protocol/xml/XMLUtils.java index 402d55a36..5356f6db0 100644 --- a/bundles/org.openhab.binding.yamahareceiver/src/main/java/org/openhab/binding/yamahareceiver/internal/protocol/xml/XMLUtils.java +++ b/bundles/org.openhab.binding.yamahareceiver/src/main/java/org/openhab/binding/yamahareceiver/internal/protocol/xml/XMLUtils.java @@ -173,7 +173,13 @@ public class XMLUtils { : "" + 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); } diff --git a/bundles/org.openhab.transform.xpath/src/main/java/org/openhab/transform/xpath/internal/XPathTransformationService.java b/bundles/org.openhab.transform.xpath/src/main/java/org/openhab/transform/xpath/internal/XPathTransformationService.java index 2dc50a934..0464dacdc 100644 --- a/bundles/org.openhab.transform.xpath/src/main/java/org/openhab/transform/xpath/internal/XPathTransformationService.java +++ b/bundles/org.openhab.transform.xpath/src/main/java/org/openhab/transform/xpath/internal/XPathTransformationService.java @@ -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();