lxml CVE-2026-41066
HIGHSeverity by source
AV:N/AC:L/PR:N/UI:N/S:U/C:H/I:N/A:N
Remote, unauthenticated, no interaction against the default parser config yields AV:N/AC:L/PR:N/UI:N; arbitrary local file read gives C:H with no integrity or availability impact.
Primary rating from GitHub Advisory.
CVSS VectorGitHub Advisory
Lifecycle Timeline
4Blast Radius
ecosystem impact- 42 pypi packages depend on lxml (40 direct, 2 indirect)
Ecosystem-wide dependent count for version 6.1.0.
DescriptionGitHub Advisory
Impact
Using either of the two parsers in the default configuration (with resolve_entities=True) allows untrusted XML input to read local files.
Patches
lxml 6.1.0 changes the default to resolve_entities='internal', thus disallowing local file access by default.
Workarounds
Setting the resolve_entities option explicitly to resolve_entities='internal' or resolve_entities=False disables the local file access.
Resources
Original report: https://bugs.launchpad.net/lxml/+bug/2146291
The default option was changed to resolve_entities='internal' for the normal XML and HTML parsers in lxml 5.0. The default was not changed for iterparse() and ETCompatXMLParser() at the time. lxml 6.1 makes the safe option the default for all parsers.
AnalysisAI
Local file disclosure via XML External Entity (XXE) injection affects the lxml Python library (versions < 6.1.0) when applications parse untrusted XML using iterparse() or ETCompatXMLParser(), whose default configuration left resolve_entities=True. An unauthenticated remote attacker who can submit crafted XML to such an endpoint can read arbitrary local files readable by the process. There is no public exploit identified at time of analysis and EPSS risk is very low (0.03%), but exploitation is trivial (CVSS 7.5, AV:N/AC:L/PR:N/UI:N) wherever these two specific parsers are used.
Technical ContextAI
lxml is a widely used Python binding to the libxml2/libxslt C libraries for XML and HTML processing. The root cause is CWE-611 (Improper Restriction of XML External Entity Reference): when a parser resolves external entities, an attacker-supplied DOCTYPE declaration can define an entity pointing at a local file path (e.g. file:///etc/passwd), and the parser substitutes the file contents into the document. lxml hardened its mainline XML and HTML parsers in 5.0 by switching the default to resolve_entities='internal', but two legacy entry points - the streaming iterparse() API and the ETCompatXMLParser() compatibility class - were overlooked and continued defaulting to resolve_entities=True. The affected component is the pip package lxml (CPE pkg:pip/lxml); the flaw is in the parser default configuration, not in libxml2 itself.
RemediationAI
Vendor-released patch: lxml 6.1.0 - upgrade to lxml >= 6.1.0, which changes the default to resolve_entities='internal' for all parsers including iterparse() and ETCompatXMLParser(), disabling local file access by default (release: https://github.com/lxml/lxml/releases/tag/lxml-6.1.0; advisory: https://github.com/lxml/lxml/security/advisories/GHSA-vfmq-68hx-4jfw). If immediate upgrade is not possible, apply the vendor workaround in code by explicitly passing resolve_entities='internal' (preserves internal entity expansion) or resolve_entities=False (disables entity resolution entirely) to every iterparse() and ETCompatXMLParser() call that processes untrusted XML; the trade-off is that resolve_entities=False will break any legitimate document that depends on entity substitution, so validate that dependent XML still parses correctly. For distro-packaged installations (SUSE, Red Hat), apply the vendor backport once released rather than side-loading pip. As defense in depth, ensure the parsing process runs with least-privilege filesystem access so that even a successful XXE reads little of value.
Vendor StatusVendor
SUSE
| Product | Status |
|---|---|
| openSUSE Tumbleweed | Fixed |
Share
External POC / Exploit Code
Leaving vuln.today
GHSA-vfmq-68hx-4jfw