What XXE Is
XXE (XML External Entity) occurs when an app parses XML with external entity support enabled. XML lets you declare entities in a DTD, and an external entity can point to a file or URL. If the parser resolves them, an attacker reads server files, makes requests on the server's behalf (SSRF), or crashes it.
How It Works
An entity is a "variable" in XML. An external entity points to a resource via SYSTEM:
<?xml version="1.0"?>
<!DOCTYPE foo [
<!ENTITY xxe SYSTEM "file:///etc/passwd">
]>
<data>&xxe;</data>
If the server reflects &xxe;, you see /etc/passwd. The root cause: user input
(the XML) is interpreted as instructions for the parser.
Exploitation Vectors
1. File read — as above (file:///).
2. SSRF — point the entity at an internal URL (e.g., cloud metadata 169.254.169.254).
3. Blind XXE (OOB) — exfiltrate over an external DTD when there's no reflected output.
4. DoS (Billion Laughs) — recursive entities blow up memory.
Defense
- Disable DTD / external entities in the parser (the main fix): Python
defusedxmlorresolve_entities=False, no_network=True; Javadisallow-doctype-decl; PHPlibxml_disable_entity_loader(true). - Prefer JSON where XML isn't required.
- Don't trust
Content-Type— verify what you actually parse.
Practice: the XXE Injection lab — read
/flag.txtvia an external entity.