XML External Entity (XXE) via XMLInputFactory

High Risk XML Security
javaxxexmlxmlinputfactoryexternal-entitiesssrf

What it is

XML External Entity (XXE) vulnerabilities occur when XMLInputFactory is configured to enable external entities or DTD support, allowing attackers to read local files, perform SSRF attacks, or cause denial of service. When XMLInputFactory processes untrusted XML with external entities enabled, attackers can craft payloads that access the file system, make network requests, or cause exponential entity expansion.

import javax.xml.stream.*;
import java.io.StringReader;

// VULNERABLE: default XMLInputFactory allows external entities
public String processXml(String xmlData) {
    try {
        XMLInputFactory factory = XMLInputFactory.newInstance();
        
        XMLStreamReader reader = factory.createXMLStreamReader(
            new StringReader(xmlData));
        
        StringBuilder result = new StringBuilder();
        while (reader.hasNext()) {
            if (reader.next() == XMLStreamConstants.CHARACTERS) {
                result.append(reader.getText());
            }
        }
        return result.toString();
    } catch (Exception e) {
        return "Error";
    }
}

// Attack payload:
// <!DOCTYPE root [<!ENTITY xxe SYSTEM "file:///etc/passwd">]>
// <root>&xxe;</root>
import javax.xml.stream.*;
import java.io.StringReader;

// SECURE: disable external entities
public String processXml(String xmlData) {
    try {
        XMLInputFactory factory = XMLInputFactory.newInstance();
        
        // Disable external entities
        factory.setProperty(
            XMLInputFactory.IS_SUPPORTING_EXTERNAL_ENTITIES, false);
        factory.setProperty(
            XMLInputFactory.SUPPORT_DTD, false);
        
        XMLStreamReader reader = factory.createXMLStreamReader(
            new StringReader(xmlData));
        
        StringBuilder result = new StringBuilder();
        while (reader.hasNext()) {
            if (reader.next() == XMLStreamConstants.CHARACTERS) {
                result.append(reader.getText());
            }
        }
        return result.toString();
    } catch (Exception e) {
        return "Error";
    }
}

💡 Why This Fix Works

The vulnerable code uses default XMLInputFactory settings which may allow external entity processing, enabling XXE attacks to read files or perform SSRF. The secure version explicitly disables external entities and DTD processing, preventing XXE exploitation.

Why it happens

Using default XMLInputFactory settings which may allow external entity processing.

Root causes

Default XMLInputFactory Configuration

Using default XMLInputFactory settings which may allow external entity processing.

Explicitly Enabling External Entities

Setting IS_SUPPORTING_EXTERNAL_ENTITIES or SUPPORT_DTD to true.

Processing Untrusted XML

Parsing XML from external sources without secure configuration.

Fixes

1

Disable External Entities

Set IS_SUPPORTING_EXTERNAL_ENTITIES and SUPPORT_DTD to false.

2

Disable Entity Replacement

Set IS_REPLACING_ENTITY_REFERENCES to false to prevent entity expansion.

3

Use JSON Instead of XML

Consider using JSON for data exchange to avoid XXE vulnerabilities entirely.

Detect This Vulnerability in Your Code

Sourcery automatically identifies xml external entity (xxe) via xmlinputfactory and many other security issues in your codebase.