MCPSafe.io
RegistryThreatsMethodologyDocsPricingScanSign in
MCPSafe.io

Security checks for MCP servers — public packages and private repos, fast or deep.

Legal

Privacy PolicyCookie PolicyTerms of ServiceSecurity disclosure

Resources

State of MCP SecuritySupportSystem statusMade in Germany 🇩🇪

© 2026 MCPSafe. All rights reserved.

GDPR — Privacy Policy
← Threat Catalog

Server Implementation

XML external entity (XXE)

HIGHAIVSS 7.5CWE: CWE-611OWASP: LLM02Agentic: T02Rule: MCP-080

A tool parses XML (SVG, RSS, SOAP, OOXML, config) with a default parser that resolves external entities — giving an attacker file read, SSRF, or denial-of-service.

What it is

XXE is the bug where an XML parser, when fed a document, follows `<!ENTITY>` declarations that reference external resources. The canonical payload replaces an entity with `file:///etc/passwd` or `http://169.254.169.254/...` and echoes it back through the parser's result. Python's stdlib (`xml.etree`, `xml.sax`, `xml.dom.minidom`), Java's `DocumentBuilder` default config, and libxml-based Node parsers all resolve entities by default.

Why it matters for MCP

MCP servers routinely accept file paths or URLs and return parsed content. Any server that handles SVG previews, RSS feeds, SOAP endpoints, or Office documents ends up feeding attacker-influenced XML to a parser. The standard library's default is unsafe — it takes an explicit opt-in (`defusedxml`, `resolve_entities=False`) to fix.

Vulnerable example

example.py
1
import xml.etree.ElementTree as ET
2
3
@server.tool()
4
def parse_feed(xml_text: str) -> dict:
5
    # Default parser resolves external entities — XXE
6
    root = ET.fromstring(xml_text)
7
    return {"root": root.tag}

Secure example

example.py
1
from defusedxml import ElementTree as ET
2
3
@server.tool()
4
def parse_feed(xml_text: str) -> dict:
5
    # defusedxml disables entity resolution, DTD processing, and billion-laughs.
6
    root = ET.fromstring(xml_text)
7
    return {"root": root.tag}

How MCPSafe detects this

We flag calls to `xml.etree.ElementTree.parse` / `fromstring`, `xml.sax.parse`, `xml.dom.minidom.parseString`, `lxml.etree.parse` without `resolve_entities=False`, and Node `libxmljs(2).parseXml` without a safe-options object. Files that import `defusedxml` or pass safe parser options are exempt.

See the full threat catalog for every documented detection.

Framework alignment

OWASP LLM Top-10 (2025)
LLM02 — Sensitive Information Disclosure
OWASP Agentic AI Top-10
T02 — Tool Misuse
AIVSS v0.5
7.5 (HIGH)AIVSS:1.0/S:HIGH/AV:N/AU:L/BR:H/CD:I

Illustrative CVEs

CVEs of the same CWE class. Not MCP-specific, but exemplify the failure mode MCPSafe detects.

  • CVE-2024-22195 — Jinja2 sandbox bypass — similar XML-context parsing class
  • CVE-2023-50447 — Pillow XML-based payload — file read via ImagePath

Further reading

  • CWE-611: XML External Entity Reference
  • OWASP: XXE Prevention Cheat Sheet

Scan an MCP server for this issue

MCPSafe runs this check — and every other rule in the catalog — on any MCP server you paste in.

Scan now