BUG-2511 Fix XXE vulnerability in initial config loaders
[controller.git] / opendaylight / config / config-persister-directory-xml-adapter / src / main / java / org / opendaylight / controller / config / persist / storage / directory / xml / XmlDirectoryPersister.java
index 92bf080662b1bc0ecc89e6427b5a0ad1cb8f63ce..3ea432e1739a7ed83047091f0a392e8918c8e45e 100644 (file)
@@ -8,6 +8,7 @@
 package org.opendaylight.controller.config.persist.storage.directory.xml;
 
 import static com.google.common.base.Preconditions.checkArgument;
 package org.opendaylight.controller.config.persist.storage.directory.xml;
 
 import static com.google.common.base.Preconditions.checkArgument;
+
 import com.google.common.base.Optional;
 import com.google.common.io.Files;
 import java.io.File;
 import com.google.common.base.Optional;
 import com.google.common.io.Files;
 import java.io.File;
@@ -22,6 +23,10 @@ import java.util.SortedSet;
 import javax.xml.bind.JAXBContext;
 import javax.xml.bind.JAXBException;
 import javax.xml.bind.Unmarshaller;
 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.opendaylight.controller.config.persist.api.ConfigSnapshotHolder;
 import org.opendaylight.controller.config.persist.api.Persister;
 import org.opendaylight.controller.config.persist.storage.file.xml.model.ConfigSnapshot;
 import org.opendaylight.controller.config.persist.api.ConfigSnapshotHolder;
 import org.opendaylight.controller.config.persist.api.Persister;
 import org.opendaylight.controller.config.persist.storage.file.xml.model.ConfigSnapshot;
@@ -90,10 +95,12 @@ public class XmlDirectoryPersister implements Persister {
         } catch (JAXBException e) {
             // In case of parse error, issue a warning, ignore and continue
             LOG.warn(
         } catch (JAXBException e) {
             // In case of parse error, issue a warning, ignore and continue
             LOG.warn(
-                    "Unable to parse configuration snapshot from {}. Initial config from {} will be IGNORED in this run. " +
-                    "Note that subsequent config files may fail due to this problem. " +
+                    "Unable to parse configuration snapshot from {}. Initial config from {} will be IGNORED in this run. ",
+                    file, file);
+            LOG.warn(
+                    "Note that subsequent config files may fail due to this problem. ",
                     "Xml markup in this file needs to be fixed, for detailed information see enclosed exception.",
                     "Xml markup in this file needs to be fixed, for detailed information see enclosed exception.",
-                    file, file, e);
+                    e);
         }
 
         return Optional.absent();
         }
 
         return Optional.absent();
@@ -102,8 +109,15 @@ public class XmlDirectoryPersister implements Persister {
     public static ConfigSnapshotHolder loadLastConfig(final File file) throws JAXBException {
         JAXBContext jaxbContext = JAXBContext.newInstance(ConfigSnapshot.class);
         Unmarshaller um = jaxbContext.createUnmarshaller();
     public static ConfigSnapshotHolder loadLastConfig(final File file) throws JAXBException {
         JAXBContext jaxbContext = JAXBContext.newInstance(ConfigSnapshot.class);
         Unmarshaller um = jaxbContext.createUnmarshaller();
-
-        return asHolder((ConfigSnapshot) um.unmarshal(file));
+        XMLInputFactory xif = XMLInputFactory.newFactory();
+        xif.setProperty(XMLInputFactory.IS_SUPPORTING_EXTERNAL_ENTITIES, false);
+        xif.setProperty(XMLInputFactory.SUPPORT_DTD, false);
+        try {
+            XMLStreamReader xsr = xif.createXMLStreamReader(new StreamSource(file));
+            return asHolder((ConfigSnapshot) um.unmarshal(xsr));
+        } catch (final XMLStreamException e) {
+            throw new JAXBException(e);
+        }
     }
 
     private static ConfigSnapshotHolder asHolder(final ConfigSnapshot unmarshalled) {
     }
 
     private static ConfigSnapshotHolder asHolder(final ConfigSnapshot unmarshalled) {