XML External Entity (XXE)
When it applies
The server parses attacker-supplied XML with external entities enabled. Any XML sink counts — SOAP, SAML, REST-with-XML, and file formats that are XML underneath (SVG, DOCX, XLSX).
Why it works
XML DTDs can declare entities that the parser resolves — including SYSTEM entities that read
local files or fetch URLs. If the parser doesn't disable external entities (the insecure
default in many libs), your entity is expanded server-side.
Method
Payloads & full variation set:
cheatsheet.mdnext to this file — work the set, not the first line.
- Detect: inject a DOCTYPE with an external entity and reference it:
<!DOCTYPE r [<!ENTITY x SYSTEM "file:///etc/passwd">]>then<r>&x;</r>— file contents in the response = in-band XXE. - Blind / OOB: no reflection → use an external DTD on your server that exfils via a
parameter entity to your Collaborator (
file:///→ your URL). DNS/HTTP hit confirms. - SSRF via XXE: point the entity at internal URLs /
169.254.169.254(→cloud-imds-ssrf). - File formats: unzip a DOCX/XLSX, inject XXE into an inner XML part, rezip, upload; SVG upload → XXE.
- Error-based: force a parse error that echoes file content in the message when output is suppressed.
Gotchas
- Modern parsers disable external entities by default — a null result may mean patched, not absent; try OOB + error-based.
php://filterbase64 wrapper reads files that break XML (binary/<).- SAML XXE is high-impact but often behind signature checks — test the pre-validation parse.
Verify success
Local file contents returned/exfiltrated, or an OOB callback proving the parser fetched your URL.
References
PortSwigger XXE labs; OWASP XXE Prevention Cheat Sheet.