Safeguard
Security

WWW XXE: Understanding and Preventing XML External Entity Attacks

XXE lets a crafted XML document read files, reach internal services, and exhaust resources. Here is how the attack works and how to shut it down.

Safeguard Research Team
Research
6 min read

An XML External Entity (XXE) attack, sometimes searched as "www xxe" because payloads reference external URLs, happens when an application parses XML with external entity resolution enabled, letting an attacker read local files, reach internal services, or exhaust resources. The root cause is almost never the application's own logic; it is a default-on feature of older XML parsers that most developers never knew was there. This guide explains the attack class conceptually, shows where it hides, and lays out the parser settings that make it go away. There are no working exploits here, only what you need to detect and prevent it.

What XXE Is

XML has a feature called entities, which are placeholders that expand into other content. Internal entities are harmless shorthand. External entities are the problem: they tell the parser to fetch content from a URI, whether a local file path or a network URL. When an application accepts XML from a user and its parser resolves external entities, the attacker can define an entity that points wherever they like and have its contents substituted into the parsed document.

The "www" in the phrase www.xxe reflects how many payloads work: the malicious entity references an external URL, sometimes an attacker-controlled web server, to either fetch a malicious Document Type Definition (DTD) or to exfiltrate data over the network. So the attack is often described in terms of the web addresses embedded in the crafted XML.

XXE sits in the OWASP Top 10 lineage under security misconfiguration and injection, and it remains common because XML is everywhere it is easy to forget: SOAP services, SAML single sign-on, SVG image uploads, DOCX and XLSX office files (which are zipped XML), RSS feeds, and configuration imports.

What an Attacker Can Do With It

The impact ranges wider than people expect. File disclosure is the classic outcome: an external entity pointed at a local path can pull the contents of sensitive files into the parsed response, exposing configuration, credentials, or keys. Because external entities can reference network URLs, XXE doubles as a server-side request forgery (SSRF) primitive, letting the attacker make the server issue requests to internal services, cloud metadata endpoints, or ports that are not reachable from outside. And a recursive entity definition can trigger a denial of service by expanding a tiny document into gigabytes in memory, the pattern known as a billion-laughs attack.

The reason this matters so much is that the vulnerable code often looks completely innocent. A single call to parse an uploaded document, with the parser's defaults, is enough.

How to Recognize Vulnerable Code

Any place that constructs an XML parser and hands it untrusted input without explicitly disabling external entities and DTDs is a candidate. The tell is the absence of hardening, not the presence of anything obviously wrong. In Java, a bare DocumentBuilderFactory or SAXParserFactory with no feature flags set is the textbook case. In .NET, older XmlReader and XmlDocument defaults historically resolved entities. In Python, xml.etree and especially lxml need explicit configuration, which is why the defusedxml library exists. In PHP, libxml_disable_entity_loader was the historical control. The specifics differ by language; the pattern is identical everywhere: default-on entity resolution meeting attacker-supplied XML.

Preventing XXE

The single most effective control is to disable DTD processing and external entities entirely, because the vast majority of applications never legitimately need them. In Java, harden the factory before parsing:

DocumentBuilderFactory dbf = DocumentBuilderFactory.newInstance();
dbf.setFeature("http://apache.org/xml/features/disallow-doctype-decl", true);
dbf.setFeature("http://xml.org/sax/features/external-general-entities", false);
dbf.setFeature("http://xml.org/sax/features/external-parameter-entities", false);
dbf.setXIncludeAware(false);
dbf.setExpandEntityReferences(false);

Disallowing the doctype declaration outright is the strongest setting: if the parser rejects any document containing a DTD, entity-based attacks cannot even be expressed. Use that whenever your inputs are plain data XML with no legitimate DTD.

In Python, reach for defusedxml in place of the standard library parsers; it ships with the dangerous features off by default:

from defusedxml.ElementTree import parse
tree = parse(untrusted_xml_stream)

The broader principles reinforce the parser hardening. Prefer less dangerous formats where you can; if an API can accept JSON instead of XML, the whole entity class disappears. Validate and, where practical, schema-check input. Run parsing with least privilege so that even a successful file read hits a process that cannot see much. And apply defense in depth by restricting outbound network access from parsing services, which blunts the SSRF and exfiltration paths.

Keeping It From Coming Back

XXE regressions are easy because the fix lives in parser configuration that a refactor or a new dependency can quietly undo. Two habits keep it fixed. First, run static analysis and DAST in CI; dynamic testing that submits crafted XML against your running endpoints, which is what a scanner like Safeguard's DAST engine does, catches an XXE-prone endpoint that a code reviewer skimmed past. Second, track your XML parsing libraries in software composition analysis, because sometimes the vulnerable behavior comes from a transitive dependency's outdated parser rather than your own code, and you want to know when one of those ships a hardening fix you should adopt.

FAQ

What does "www xxe" mean?

It refers to XML External Entity attacks, where a crafted XML document uses external entities pointing at URLs (often http:// or https:// addresses, hence "www") to read files, reach internal services, or exfiltrate data. It is the same thing as XXE.

Is XXE still a common vulnerability?

Yes. XML appears in SOAP, SAML, SVG uploads, office documents, feeds, and config imports, and many parsers historically resolved external entities by default. Anywhere untrusted XML is parsed without hardening is a candidate.

What is the best single fix for XXE?

Disable DTD processing and external entities in your XML parser. Where your inputs never need a DTD, reject any document that contains one outright, which prevents entity-based attacks from even being expressed.

Can XXE lead to more than reading files?

Yes. Because external entities can reference network URLs, XXE also enables server-side request forgery against internal services and cloud metadata endpoints, and recursive entity expansion can cause denial of service.

Never miss an update

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