XML External Entity (XXE)
XXE injection exploits XML parsers to read local files, perform SSRF, or cause denial of service by defining malicious external entity references in XML input.
What Is XXE?
XML External Entity (XXE) injection targets applications that parse XML input. XML allows defining "entities" — shortcuts that expand to values. When an XML parser is configured to resolve external entities, an attacker can use them to read arbitrary local files or make server-side HTTP requests (SSRF).
How It Works
A file upload endpoint that processes XML:
# Vulnerable — lxml with external entity resolution enabled
from lxml import etree
@app.post("/upload")
async def process_xml(file: UploadFile):
content = await file.read()
tree = etree.fromstring(content) # Resolves external entities by default in some configs
return {"data": tree.find("name").text}An attacker uploads:
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE foo [
<!ENTITY xxe SYSTEM "file:///etc/passwd">
]>
<root>
<name>&xxe;</name>
</root>The parser substitutes &xxe; with the contents of /etc/passwd — the response contains the server's user database.
SSRF via XXE:
<!DOCTYPE foo [
<!ENTITY xxe SYSTEM "http://169.254.169.254/latest/meta-data/iam/security-credentials/">
]>Billion Laughs (DoS):
<!DOCTYPE bomb [
<!ENTITY a "aaa...">
<!ENTITY b "&a;&a;&a;&a;&a;&a;&a;&a;&a;&a;">
<!ENTITY c "&b;&b;&b;&b;&b;&b;&b;&b;&b;&b;">
]>
<root>&c;</root>Real-World Impact
- Local file read —
/etc/passwd,.env, private keys, application source code - SSRF — access cloud metadata and internal services via entity URLs
- Denial of Service — billion laughs attack exhausts memory
- Port scanning — enumerate internal services via error-based XXE
How to Fix
Disable external entity processing entirely:
# lxml — disable completely
from lxml import etree
parser = etree.XMLParser(
resolve_entities=False,
no_network=True,
load_dtd=False,
)
tree = etree.fromstring(content, parser=parser)# defusedxml — safe XML parsing library (recommended)
import defusedxml.ElementTree as ET
tree = ET.fromstring(content) # Safe by default, raises on XXE attemptsPrefer JSON over XML for APIs and file formats where XML isn't required.
If XML is required — use a strict allowlist of permitted elements and attributes, and never allow DOCTYPE declarations from untrusted input.
What VibeWShield Detects
VibeWShield submits XXE payloads to endpoints accepting XML content (Content-Type: application/xml, text/xml) or file uploads. It checks for file content patterns in responses and timing anomalies from SSRF-based XXE.
Free security scan
Test your app for XML External Entity (XXE)
VibeWShield automatically checks for XML External Entity (XXE) and 40+ other vulnerabilities using 63 scanners — in under 3 minutes, no signup required.
Scan your app free