flawopen.com/XXE/Python xml.etree
Partly, and the nuance matters. xml.etree.ElementTree does not resolve external entities, so the classic file:///etc/passwd read does not work against it. It is still exposed to entity-expansion denial of service, and other Python XML APIs — notably lxml — behave differently. The standard-library documentation's own recommendation is to use defusedxml for untrusted input.
# ElementTree: no external entity read, # but expansion DoS is possible import xml.etree.ElementTree as ET ET.fromstring(untrusted) # lxml: resolves external entities in # some configurations — this is the # genuinely dangerous one from lxml import etree etree.fromstring(untrusted) # "Billion laughs": nested entities # expanding to gigabytes of memory # from a few hundred bytes of input.
# Drop-in replacements, hardened from defusedxml.ElementTree import fromstring root = fromstring(untrusted) # If you must use lxml directly, # configure the parser explicitly: from lxml import etree parser = etree.XMLParser( resolve_entities=False, no_network=True, load_dtd=False, huge_tree=False, ) root = etree.fromstring(untrusted, parser)
Because the exposure differs per API and has changed across Python and library versions, the reliable approach is to standardise on defusedxml for anything parsing untrusted XML rather than tracking which parser is currently safe against which variant.
Python's own documentation includes a section on XML vulnerabilities that compares the standard library modules against each attack type and points to defusedxml as the mitigation. The package provides drop-in replacements for the standard APIs with entity processing and network access disabled, so adopting it is usually a one-line import change per call site rather than a rewrite.
It is not vulnerable to the file-read variant, which is the one people usually mean by "XXE". It is still worth routing untrusted input through defusedxml to cover expansion denial of service and to avoid depending on parser-specific behaviour that may differ across versions and platforms.
For untrusted input with default settings, lxml has the larger exposure because it supports external entity resolution and network fetching. It is an excellent library — it simply needs an explicitly configured parser when the input is hostile.
All are XML and all carry the same risks. SVG uploads and SAML assertions are particularly common XXE entry points because both are typically accepted from untrusted parties and parsed with default settings.