Hello! Welcome back to our module on advanced server-side vulnerabilities.
In our last lesson, you got hands-on experience exploiting insecure deserialization. You learned how an application that blindly trusts and parses structured data (a Python Pickle object) can be tricked into executing arbitrary code. Today, we're exploring a very similar theme but with a different data format: XML.
Our learning outcome is to identify XML External Entity (XXE) injection vulnerabilities by manipulating XML parsers. We'll cover how to spot and exploit these vulnerabilities, not just in obvious places, but also in hidden attack surfaces that are often missed by beginners. This is a critical skill for both penetration testing and bug bounty hunting.
We will cover:
- The fundamentals of XML, entities, and how they become a vulnerability.
- How to perform a classic XXE attack to read local files from a server.
- Advanced techniques to find XXE in non-obvious places, like file uploads and by manipulating request headers.
1. Understanding the Root Cause: What is an XXE Vulnerability?
XML (eXtensible Markup Language) is a format for structuring, storing, and transporting data. A key feature of XML is the ability to define entities. Think of an entity as a variable or a macro. For example, you could define an entity &company_name; to represent "ACME Corp".
The vulnerability arises when an XML parser is configured to process external entities. An external entity is one whose value is loaded from an external source, like a file path or a URL. An attacker can supply malicious XML that defines an external entity pointing to a sensitive local file (e.g., /etc/passwd). When the application parses this XML, it reads the file and may embed its contents into the response, disclosing it to the attacker.
This is fundamentally a parser vulnerability, where the line between data and instructions becomes blurred. The parser is trusted to process data, but an attacker tricks it into executing an instruction (read this file).
Let's start with a foundational reading from PortSwigger, the creators of Burp Suite.
XML external entity (XXE) injection
This article provides a clear, concise definition of XXE and explains why these vulnerabilities occur. It's the best place to start for a solid theoretical foundation.
Read the sections 'What is XML external entity injection?' and 'How do XXE vulnerabilities arise?'. Focus on understanding that the vulnerability stems from standard parsers supporting a dangerous feature of the XML specification by default.
To see this concept explained visually, the following video provides a quick and effective summary.
Remediate XXE (XML External Entity Injection)
This short clip from The Cyber Mentor demonstrates exactly how a standard XML entity is turned into a malicious external entity that points to a local file.
Watch from 01:17 to 02:11. Pay attention to the distinction between a regular entity and an external entity using the SYSTEM keyword.

2. The Classic Attack: Identifying and Exploiting Basic XXE
The most straightforward scenario for XXE is when an application is clearly communicating with the server using XML. You can spot this by looking for a Content-Type: application/xml or Content-Type: text/xml header in HTTP requests, or by simply seeing XML data in a request body.
The attack payload has two parts:
- Define the entity: You add a
<!DOCTYPE>element to define your malicious external entity. This points the parser to the resource you want to access.<!DOCTYPE foo [ <!ENTITY xxe SYSTEM "file:///etc/passwd"> ]> - Reference the entity: You use the entity you just defined somewhere in the XML data. The
∧are used to reference it.<productId>&xxe;</productId>
When the parser processes the <productId>, it replaces &xxe; with the content of the /etc/passwd file. If the application reflects the product ID in its response, you'll see the file's contents.
Let's turn to a practical demonstration of this attack using Burp Suite.
Remediate XXE (XML External Entity Injection)
This video segment demonstrates the entire process of finding and exploiting a basic XXE vulnerability in a web application's 'check stock' feature.
Watch from 02:11 to 06:53. Observe how the request is intercepted in Burp Suite, sent to Repeater, and then modified with the XXE payload. Notice how the response changes from an error to reflecting the contents of the /etc/passwd file.
The PortSwigger article you read earlier also provides a clear, text-based example of this exact attack. You can refer to the section "Exploiting XXE to retrieve files" in resource LINK for a static payload example.
Test your understanding!
You are testing an application that uses the following XML to update a user's profile:
<?xml version="1.0" encoding="UTF-8"?>
<profile>
<name>testuser</name>
<email>test@example.com</email>
</profile>
You suspect an XXE vulnerability. Modify the XML above to construct a payload that attempts to read the server's hostname, which is typically found in /etc/hostname on Linux systems.
Show answer
You would need to add a DOCTYPE declaration to define an entity and then reference that entity within one of the existing tags, like <email>.
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE profile [ <!ENTITY xxe SYSTEM "file:///etc/hostname"> ]>
<profile>
<name>testuser</name>
<email>&xxe;</email>
</profile>
If the application is vulnerable and reflects the email address in the response, you would see the server's hostname.
3. Finding Hidden Attack Surfaces for XXE
Relying on seeing Content-Type: application/xml will cause you to miss most XXE vulnerabilities. Expert testers know how to find "hidden" attack surfaces. Let's explore two of the most common ones.
Scenario A: XXE via File Uploads
Many modern applications allow users to upload files like avatars, documents, or data sheets. Some of these file formats are actually XML-based. A prime example is the SVG (Scalable Vector Graphics) image format. Others include office formats like DOCX and XLSX.
If an application allows you to upload an SVG file and processes it on the server (e.g., to resize or validate it), you can embed an XXE payload directly into the SVG file's XML structure.
The next segment of The Cyber Mentor's video demonstrates this perfectly.
Remediate XXE (XML External Entity Injection)
This is an excellent demonstration of a more advanced XXE attack. It shows how an attacker can find an XXE vulnerability in a feature that doesn't appear to use XML at all on the surface.
Watch from 06:53 to 13:00. Note the methodology: the target is a file upload in a comment section. The attacker crafts a malicious SVG file containing an XXE payload and uploads it, causing the server to process the malicious XML and reveal the hostname in the rendered image.
Scenario B: XXE via Content-Type Modification
Sometimes, an application endpoint is designed to handle multiple content types, even if it defaults to something like JSON or standard form data. A common example is a web API that can respond to both application/json and application/xml for broader compatibility.
You can test for this by taking a normal POST request (e.g., with a JSON body) and trying to:
- Change the
Content-Typeheader toapplication/xml. - Reformat the request body from JSON to the equivalent XML structure.
- Inject your XXE payload into the new XML body.
If the server's framework is configured to automatically parse XML when it sees the corresponding content type, your payload will be processed.
XML external entity (XXE) injection
The PortSwigger article covers these hidden attack surfaces well. It provides concise explanations for both the file upload and content-type modification vectors.
Read the subsections 'XXE attacks via file upload' and 'XXE attacks via modified content type' under the main section 'Finding hidden attack surface for XXE injection'. This will solidify your understanding of the concepts shown in the videos.
A final technique worth knowing is the XInclude attack. If you find you can inject content into a server-side XML document but cannot control the DOCTYPE, you may be able to use <xi:include> to include external files. This is another way to force the parser to read local files. The PortSwigger article (LINK, section 3) also provides a good example of this.
Conclusion
In this lesson, you learned how to identify and test for XML External Entity injection, a serious vulnerability stemming from insecure XML parsers.
Key Takeaways:
- Core Vulnerability: XXE occurs when an XML parser processes an external entity defined by an attacker, allowing them to read local files or interact with other systems.
- Classic Payload: The attack requires defining a
DOCTYPEwith a maliciousSYSTEMentity and referencing it within the XML body. - Hidden Attack Surfaces: You must look beyond obvious XML requests. Key hidden vectors include:
- File Uploads: Exploiting XML-based file formats like SVG or DOCX.
- Content-Type Switching: Forcing an endpoint to parse XML by modifying the
Content-Typeheader.
- Manual Testing is Key: While scanners can find basic XXE, identifying hidden vulnerabilities often requires the manual, creative techniques you learned today.
Next Lesson Preview:
So far, we've used XXE to read files whose contents are returned directly in the application's response. But what if they aren't? And what else can we do besides reading files? In our next lesson, we will explore Server-Side Request Forgery (SSRF). You will learn how to identify and exploit SSRF, and we will revisit XXE as a powerful technique to trigger SSRF attacks, enabling you to scan internal networks and interact with sensitive internal services.