XML External Entity (XXE) Attacks: Detection and Prevention
Many developers assume they do not use XML. Then they discover that their app accepts SVG uploads, parses DOCX files, handles SAML logins or integrates with a legacy partner API. All of those involve XML, and XML parsers can be dangerous by default.
How XXE works
XML supports "entities," which are like variables. External entities can load content from a file path or URL. If a parser processes external entities in untrusted input, an attacker can do this:
<?xml version="1.0"?>
<!DOCTYPE data [
<!ENTITY xxe SYSTEM "file:///etc/passwd">
]>
<data>&xxe;</data>
If the application reflects the parsed value, the attacker reads the server's files.
What attackers can do
- Read local files: configuration, credentials and source code.
- Perform SSRF: point the entity at internal URLs, including cloud metadata services.
- Exfiltrate data blind, using parameter entities and an external server when output is not reflected.
- Cause denial of service with recursive entity expansion, known as the "billion laughs" attack.
Where XML hides
- File uploads: SVG images, DOCX, XLSX and PPTX files, which are ZIP archives of XML.
- SAML single sign-on responses.
- SOAP APIs and legacy integrations.
- RSS and Atom feeds imported from URLs.
- APIs that accept XML as an alternative content type, sometimes without developers realising. Try sending
Content-Type: application/xmlto a JSON endpoint.
How to prevent XXE
The core fix is simple: disable DTDs and external entities in every XML parser.
// Java example
DocumentBuilderFactory f = DocumentBuilderFactory.newInstance();
f.setFeature("http://apache.org/xml/features/disallow-doctype-decl", true);
Additional steps:
- Use safe libraries. In Python,
defusedxmlprotects against XXE and expansion attacks. - Keep parsers updated. Many modern parsers are safe by default, but older versions are not.
- Prefer JSON for new APIs.
- Process uploads in isolation, without network access, so SSRF via XXE has nowhere to go.
- Validate content types and reject XML on endpoints that do not need it.
Testing for XXE
Testing involves sending XML payloads with external entities to every XML-accepting input, including file uploads and alternative content types, and using out-of-band detection for blind cases. SecurityInfinity agents test for XXE in uploads and APIs and point to the parser configuration that needs changing. Start free.
Frequently asked questions
Are JSON APIs vulnerable to XXE?
Not directly, but some frameworks also accept XML on the same endpoint if the content type is changed. Test this explicitly.
Can SVG uploads cause XXE?
Yes. SVG is XML, and if your server parses or converts SVGs with an unsafe parser, XXE is possible.
Is XXE still in the OWASP Top 10?
XXE was its own category in 2017. Since 2021 it is grouped under Security Misconfiguration, as it is usually caused by unsafe parser defaults.