Skip to content

XML External Entity (XXE) Processing

What does this mean ?

An XML External Entity attack is a type of attack against an application that parses XML input. This attack occurs when XML input containing a reference to an external entity is processed by a weakly configured XML parser. Some applications use the XML format to transmit data between the browser and the server. Applications that do this virtually always use a standard library or platform API to process the XML data on the server. XXE vulnerabilities arise because the XML specification contains various potentially dangerous features, and standard parsers support these features even if they are not normally used by the application.

What can happen ?

This attack may lead to the disclosure of confidential data, denial of service, server side request forgery, port scanning from the perspective of the machine where the parser is located, and other system impacts. Attacks can include disclosing local files, which may contain sensitive data such as passwords or private user data, using file: schemes or relative paths in the system identifier. Since the attack occurs relative to the application processing the XML document, an attacker may use this trusted application to pivot to other internal systems, possibly disclosing other internal content via http(s) requests or launching a CSRF attack to any unprotected internal services.

Recommendation

  • Virtually all XXE vulnerabilities arise because the application's XML parsing library supports potentially dangerous XML features that the application does not need or intend to use. The easiest and most effective way to prevent XXE attacks is to disable those features.
  • Generally, it is sufficient to disable resolution of external entities and disable support for XInclude. This can usually be done via configuration options or by programmatically overriding default behavior. Consult the documentation for your XML parsing library or API for details about how to disable unnecessary capabilities.

Sample Code

Vulnerable :

XmlReaderSettings settings = new XmlReaderSettings();
settings.ProhibitDtd = false;
XmlReader reader = XmlReader.Create(inputXml, settings);
XmlReaderSettings settings = new XmlReaderSettings();
settings.DtdProcessing = DtdProcessing.Parse;
XmlReader reader = XmlReader.Create(inputXml, settings);

Non Vulnerable :

//Avoid overriding the secure settings
XmlReader reader = XmlReader.Create(inputXml);
XmlReaderSettings settings = new XmlReaderSettings();
settings.ProhibitDtd = true;
XmlReader reader = XmlReader.Create(inputXml, settings);
XmlReaderSettings settings = new XmlReaderSettings();
settings.DtdProcessing = DtdProcessing.Ignore;
XmlReader reader = XmlReader.Create(inputXml, settings);

Vulnerable :

DocumentBuilder db = DocumentBuilderFactory.newInstance().newDocumentBuilder();
Document doc = db.parse(input);

Non Vulnerable :

DocumentBuilderFactory dbf = DocumentBuilderFactory.newInstance();
dbf.setFeature(XMLConstants.FEATURE_SECURE_PROCESSING, true);
DocumentBuilder db = dbf.newDocumentBuilder();
Document doc = db.parse(input);
DocumentBuilderFactory dbf = DocumentBuilderFactory.newInstance();
dbf.setFeature("http://apache.org/xml/features/disallow-doctype-decl", true);
DocumentBuilder db = dbf.newDocumentBuilder();
Document doc = db.parse(input);

Vulnerable :

$xml = file_get_contents("xxe.xml");
$doc = simplexml_load_string($xml, "SimpleXMLElement", LIBXML_NOENT); // Noncompliant (LIBXML_NOENT enable external entities substitution)
$doc = new DOMDocument();
$doc->load("xxe.xml", LIBXML_NOENT); // Noncompliant (LIBXML_NOENT enable external entities substitution)
$reader = new XMLReader();
$reader->open("xxe.xml");
$reader->setParserProperty(XMLReader::SUBST_ENTITIES, true); // Noncompliant (SUBST_ENTITIES enable external entities substitution)

Non Vulnerable :

$xml = file_get_contents("xxe.xml");
$doc = simplexml_load_string($xml, "SimpleXMLElement"); // Compliant (external entities substitution are disabled by default)
$doc = new DOMDocument();
$doc->load("xxe.xml"); // Compliant (external entities substitution are disabled by default)
$reader = new XMLReader();
$reader->open("xxe.xml");
$reader->setParserProperty(XMLReader::SUBST_ENTITIES, false); // Compliant (SUBST_ENTITIES set to false)

References