XML External Entity (XXE) Injection is a web security vulnerability that occurs when an application processes XML input containing references to external entities without proper validation or restrictions.
An attacker can exploit XXE vulnerabilities to achieve various malicious goals:
When processed by a vulnerable XML parser, this payload:<!ENTITY xxe SYSTEM "file:///etc/passwd">will result in the content of the /etc/passwd file being read and returned to the attacker.
This allows the attacker to read sensitive system files that should not be accessible.
Real-world Occurrences of XXE Injection
Facebook XXE Vulnerability (2014)
Facebook's "Forgot your password?" functionality was found to be vulnerable to XXE injection. An attacker could read arbitrary files from Facebook's servers, and potentially run arbirary code. The vulnerability occurred because the XML parser used to process user-supplied XML data had external entity processing enabled. Facebook fixed the issue through their bug bounty program before any known exploitation.
Uber XXE Vulnerability (2016)
A security researcher identified an XXE vulnerability in a third-party backup software utilized by Uber. This flaw allowed unauthorized access to internal files. The vulnerability could have given an attacker access to the user backup data of any company using the software, including Uber. Uber fixed the issue through their bug bounty program before any known exploitation.
Fixing XXE Injections
The most effective way to prevent XXE attacks is to disable XML external entity and DTD processing in your XML parser configuration.
Different XML parsers have different methods to disable these features, but the general principle is to turn off support for external entities and DTD processing entirely unless absolutely necessary. If DTD processing is required, external entities should still be disabled.
The vulnerable code uses default XML parser settings which allow external entities.
The fix explicitly disables DOCTYPE declarations and external entities.
Additional security features are enabled to prevent XXE attacks.
The XML parser will now reject any attempts to use external entities.
Vulnerable Code
from xml.etree.ElementTree import parse
tree = parse(xmlSource)
Fixed Code
from defusedxml.ElementTree import parse
from defusedxml.ElementTree import DefusedXMLParser
parser = DefusedXMLParser(forbid_dtd=True)
tree = parse(xmlSource, parser=parser)
Fix Explanation
The vulnerable code uses the standard XML parser which is vulnerable to XXE.
The fix uses the defusedxml library, which is specifically designed to prevent XML attacks.
DTD processing is explicitly forbidden.
The parser will safely handle XML input without allowing external entities.
Vulnerable Code
$xml = simplexml_load_string($xmlStr);
$dom = new DOMDocument();
$dom->loadXML($xmlStr);
The vulnerable code processes XML without any security controls.
The fix disables external entity loading using libxml_disable_entity_loader().
Additional flags are used to control XML parsing behavior.
External entities and potentially dangerous features are disabled.
Vulnerable Code
XmlDocument xmlDoc = new XmlDocument();
xmlDoc.Load(xmlFile);
The vulnerable code uses default XML processing settings.
The fix explicitly prohibits DTD processing.
The XML resolver is set to null to prevent external entity resolution.
The XML document is loaded using secure settings.
Vulnerable Code
const xml2js = require('xml2js');
const parser = new xml2js.Parser();
parser.parseString(xml);
The vulnerable code uses default parser settings which may process entities.
The fix explicitly disables entity processing.
Additional security options are set to ignore entities.
The parser will safely handle XML without processing external entities.
The vulnerable code uses default Nokogiri settings which may be unsafe.
The fix disables network access and entity expansion.
ParseOptions are used to control XML processing behavior.
The parser will safely handle XML without allowing external entities.