XML External Entity (XXE)

What is XXE?

Some applications use XML (Extensible Markup Language) to transfer data. The XML spec includes features for representing data using entities - for example &amp; for &, &lt; for <, &gt; for >. An external entity is a custom entity whose definition lives outside the document - the parser needs to locate and fetch it when processing the XML. We can abuse this to read files from the server and in some cases achieve remote code execution.


Basic XML structure

In the lab example, the website is asking us for an XML file with this structure:

<creds><user>username</user> <password>password</password></creds>

Or in pretty:

<creds>
    <user>username</user>
    <password>password</password>
</creds>

Now create a safe XML file we can upload first to test:

<?xml version="1.0" encoding="UTF-8"?>
<creds>
    <user>username</user>
    <password>password</password>
</creds>

XXE Payload

Here is a sample basic XXE payload to read /etc/passwd from: https://payloadplayground.com/generators/xxe

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

Now it is pretty straightforward - we take the safe payload and replace a variable with &xxe;

<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE creds [
  <!ELEMENT creds ANY>
  <!ENTITY xxe SYSTEM "file:///etc/passwd">
]>
<creds>
  <user>&xxe;</user>
  <password>anything</password>
</creds>

You can see the output, and if you want to read it in a better format - check page source (CTRL + U).


Other XXE attack types

Not all XXE is classic file reading. There are several variants:

  • Classic XXE - read files directly as shown above
  • Base64 encoded - use PHP wrappers to base64-encode file contents (useful when raw file content breaks the XML): php://filter/convert.base64-encode/resource=/etc/passwd
  • Blind XXE (out-of-band) - the server doesn’t return the entity content in the response. Instead, you make it send the data to your server (webhook.site, Burp Collaborator, or your own listener)
  • PHP wrappers inside XXE - combine XXE with PHP stream wrappers for more flexibility
  • Technology-specific payloads - Java, .NET, etc. have their own XXE tricks

Testing tip

If an API endpoint expects JSON, try sending XML instead. Some backends accept both content types. If it processes your XML, test for XXE - these cases are often overlooked and great for bug bounties.

Change the Content-Type header:

Content-Type: application/xml

Then send XML in the body instead of JSON.

Resources

Testing Checklist

  • Identify any endpoint that accepts or processes XML input - file uploads, API endpoints, SOAP services, configuration imports, bulk update forms
  • Upload a safe, well-formed XML file first to confirm the application parses it correctly and understand the expected structure
  • Test classic XXE file read by defining an external entity pointing to file:///etc/passwd and referencing it in a displayed field (e.g., <user>&xxe;</user>)
  • If raw file content breaks the XML parsing, try base64 encoding via PHP wrappers: php://filter/convert.base64-encode/resource=/etc/passwd
  • If no output is returned in the response (blind XXE), attempt out-of-band exfiltration by pointing the entity to webhook.site, Burp Collaborator, or your own listener
  • Test API endpoints that expect JSON by switching the Content-Type header to application/xml and sending XML in the body - backends that accept both formats are often overlooked and great for bug bounties
  • Try reading application config files that may contain credentials: wp-config.php, db.php, .env, web.config, appsettings.json
  • Use PHP wrappers inside XXE (php://filter/convert.base64-encode/resource=db.php) to read PHP source files without them being executed
  • Check PayloadsAllTheThings for technology-specific payloads - Java, .NET, PHP each have their own XXE tricks
  • Include in report: the file read or data exfiltrated, the exact XML payload used, the endpoint and content type, and impact (sensitive file disclosure, credential theft, potential RCE)