XML standard allows the use of entities, declared in the DOCTYPE of the document, which can be internal or external.

When parsing the XML file, the content of the external entities is retrieved from an external storage such as the file system or network, which may lead, if no restrictions are put in place, to arbitrary file disclosures or server-side request forgery (SSRF) vulnerabilities.

<?xml version="1.0" encoding="utf-8"?>
<!DOCTYPE person [
  <!ENTITY file SYSTEM "file:///etc/passwd">
  <!ENTITY ssrf SYSTEM "https://internal.network/sensitive_information">
]>

<person>
  <name>&file;</name>
  <city>&ssrf;</city>
  <age>18</age>
</person>

It’s recommended to limit resolution of external entities by using one of these solutions:

Noncompliant Code Example

SimpleXML object:

$xml = file_get_contents("xxe.xml");
$doc = simplexml_load_string($xml, "SimpleXMLElement", LIBXML_NOENT); // Noncompliant (LIBXML_NOENT enable external entities substitution)

DOMDocument object:

$doc = new DOMDocument();
$doc->load("xxe.xml", LIBXML_NOENT); // Noncompliant (LIBXML_NOENT enable external entities substitution)

XMLReader object:

$reader = new XMLReader();
$reader->open("xxe.xml");
$reader->setParserProperty(XMLReader::SUBST_ENTITIES, true); // Noncompliant (SUBST_ENTITIES enable external entities substitution)

Compliant Solution

SimpleXML object:

$xml = file_get_contents("xxe.xml");
$doc = simplexml_load_string($xml, "SimpleXMLElement"); // Compliant (external entities substitution are disabled by default)

DOMDocument object:

$doc = new DOMDocument();
$doc->load("xxe.xml"); // Compliant (external entities substitution are disabled by default)

XMLReader object:

$reader = new XMLReader();
$reader->open("xxe.xml");
$reader->setParserProperty(XMLReader::SUBST_ENTITIES, false); // Compliant (SUBST_ENTITIES set to false)

See