XXE (XML External Entity) injection occurs when an app parses attacker-supplied XML with a parser that resolves external entities. The attacker defines a malicious entity and the parser fetches whatever it points to, enabling local file disclosure (config, credentials, keys), SSRF (reaching internal services and cloud metadata), and denial of service (billion-laughs). It hides wherever XML is accepted — SOAP, XML APIs, SAML, and DOCX/XLSX/SVG uploads (all XML under the hood). Blind variants exfiltrate out-of-band. The definitive fix: disable external entities and DTD processing in the parser — simple and complete, unlike filtering. Full explainer below; XXE is part of every web app test we run.
// 01 How XXE works
XML has a feature called entities — placeholders that expand to some value when the document is parsed. Most are harmless, but XML also supports external entities, which tell the parser to fetch content from a URI (a file path, a URL) and substitute it in. The vulnerability is simple: if an application parses user-supplied XML with a parser that resolves external entities (historically the default in many libraries), an attacker can define an external entity pointing at, say, file:///etc/passwd or an internal URL, and the parser dutifully retrieves it and includes the content in the parsed output. The attacker never needs code execution — they just abuse a legitimate XML feature that should have been turned off. That gap between “XML feature” and “attacker capability” is the whole vulnerability.
// 02 What an attacker can do
File disclosure
Read sensitive files — config, credentials, private keys, source — off the server's filesystem.
SSRF
Make the server request internal services or cloud metadata — a stepping stone to deeper compromise.
Denial of service
Entity-expansion (billion-laughs) attacks that exhaust server memory.
Out-of-band exfil
In blind cases, exfiltrate data to an attacker-controlled server.
The two that matter most in practice are file disclosure and SSRF. File disclosure hands the attacker your secrets; SSRF turns your server into a launch point against your internal network and cloud — which is why XXE so often chains into a much larger compromise rather than staying a “read one file” bug.
// 03 Blind XXE & out-of-band exfiltration
The straightforward case returns the fetched content in the app's response, so the attacker sees the file. But mature apps often don't echo parsed XML back — that's blind XXE, and it's where weaker tests give up. Skilled attackers (and testers) don't. Using out-of-band techniques, they make the parser send the extracted data to an attacker-controlled server — embedding the file's contents in a URL the server is tricked into requesting, or using external DTDs to stage a two-step exfiltration. The impact is identical to the visible case; only the detection is harder. This is precisely the kind of finding a scanner misses and a human finds, because confirming blind XXE requires setting up a listener and reasoning about the parser's behaviour rather than matching a signature.
// 04 Where XXE hides in modern apps
“We don't use XML” is the sentence that precedes many XXE findings, because XML is lurking where you don't see it. The obvious spots are SOAP web services and XML API endpoints. The non-obvious ones cause the real damage: SAML single sign-on is XML-based, so authentication flows can be vulnerable; and a huge range of file formats are XML under the hood — DOCX, XLSX, PPTX, SVG and others are zipped XML. So a feature as innocent as “upload your profile picture” (accepting SVG) or “import a spreadsheet” (XLSX) can be an XXE entry point. A thorough test probes every place XML could be parsed, especially document and image upload flows — the ones most teams never think to check, and which tie into broader input-handling risks.
// 05 How to test and fix it
Testing: at each XML entry point, submit a payload defining an external entity pointing to a local file or an attacker-controlled URL, and observe whether the parser resolves it — directly in the response, or out-of-band via a listener for blind cases. Include the sneaky vectors: SAML, and SVG/DOCX/XLSX uploads. Fixing: the definitive remedy is to disable external entity and DTD processing in the parser — this removes the vulnerability at the root, and it's what OWASP recommends. Every language and XML library has specific flags to turn off DTDs and external entities; set them everywhere XML is parsed. Where XML isn't actually needed, prefer JSON. Input filtering and WAFs help at the margins but are not a substitute: the safe parser configuration is simple and complete, while filtering is easy to bypass. Every web app engagement we run tests for XXE across all these vectors, per our methodology.
// 06 Frequently asked questions
What is XXE injection?
A vulnerability that arises when an app parses XML input with a parser configured to resolve external entities. An attacker embeds a malicious external entity in the XML, and the parser fetches and includes what it points to — enabling local file reads, server-side request forgery, and sometimes denial of service. It exists because many XML parsers historically resolved external entities by default.
What can an attacker do with XXE?
Local file disclosure (config, credentials, keys), SSRF (making the server request internal services or cloud metadata, leading to further compromise), and denial of service (billion-laughs entity expansion). In blind variants, attackers use out-of-band techniques to exfiltrate data. Impact ranges from information disclosure to a foothold for deeper attacks.
Where does XXE hide?
Anywhere XML is accepted — SOAP and XML APIs, SAML authentication (XML-based), and file uploads for formats that are XML under the hood like DOCX, XLSX, SVG and PPTX. Because these aren't obviously XML, XXE is often missed. A tester probes every XML entry point, including document and image upload flows.
How do you prevent XXE?
Disable external entity and DTD processing in the XML parser entirely — this removes it at the root and is OWASP's recommendation. Each language/parser has specific settings. Where XML isn't needed, prefer JSON. Input validation and WAFs help but aren't a substitute, because the safe configuration is simple and complete while filtering is easy to bypass.
// 07 Related reading
- SSRF, IMDSv2 & STS — where XXE-driven SSRF leads in the cloud.
- OWASP Top 10 in real engagements and the session management checklist.
- Web application penetration testing and our methodology.