Skip to main content
CVE Vulnerability Database

CVE-2026-6879: XML Element XPath DOS Vulnerability

CVE-2026-6879 is a denial of service vulnerability affecting XML Element XPath operations with index predicates. This flaw causes O(n^2) time complexity in findall() and iterfind() methods. This article covers technical details, performance impact, affected operations, and mitigation strategies.

Published:

CVE-2026-6879 Overview

CVE-2026-6879 is an algorithmic complexity vulnerability in the Python standard library xml.etree.ElementPath module. The Element.findall() and fully-consumed Element.iterfind() methods exhibit O(n^2) time complexity when using XPath index predicates such as [1], [last()], or [last()-N] on XML documents containing many same-tag siblings. The Element.find() method is affected only when the first match resides near the end of the sibling list, since .//item[1] short-circuits after the first match. The flaw is tracked under CWE-407: Inefficient Algorithmic Complexity.

Critical Impact

Applications that apply XPath index predicates to attacker-influenced XML with many same-tag siblings may experience CPU exhaustion and degraded availability.

Affected Products

  • CPython xml.etree.ElementTree (ElementPath module)
  • Python applications invoking Element.findall() with index predicates
  • Python applications invoking Element.iterfind() or Element.find() with [last()] or [last()-N] predicates

Discovery Timeline

  • 2026-07-28 - CVE-2026-6879 published to NVD
  • 2026-07-28 - Last updated in NVD database

Technical Details for CVE-2026-6879

Vulnerability Analysis

The vulnerability resides in the index-predicate selector implementation in Lib/xml/etree/ElementPath.py. For every candidate element in the result set, the selector rebuilt the full sibling list by calling parent.findall(elem.tag) and then indexed into it. When a parent contains N same-tag children, each of the N candidates triggers an O(N) sibling enumeration, yielding overall O(N²) work. Processing XML documents with tens or hundreds of thousands of same-tag siblings can therefore consume disproportionate CPU time relative to the size of the input.

Root Cause

The root cause is the absence of memoization in the prepare_predicate handler for numeric index predicates. The original code executed list(parent.findall(elem.tag)) on every iteration rather than caching the resolved child at elems[index] per (parent, tag) pair. Repeated linear scans of identical sibling lists produced the quadratic behavior classified as [CWE-407].

Attack Vector

Exploitation requires an application to accept untrusted XML and evaluate XPath index predicates against it using xml.etree.ElementTree. An attacker submits a document containing a large number of same-tag siblings, causing extended CPU consumption inside the interpreter. The impact is limited to availability, and the CVSS 4.0 vector reflects high attack complexity and required privileges.

python
                index = -1
         def select(context, result):
             parent_map = get_parent_map(context)
+            cache = {}
             for elem in result:
                 try:
                     parent = parent_map[elem]
+                except KeyError:
+                    continue
+                key = (parent, elem.tag)
+                if key not in cache:
                     # FIXME: what if the selector is "*" ?
-                    elems = list(parent.findall(elem.tag))
-                    if elems[index] is elem:
-                        yield elem
-                except (IndexError, KeyError):
-                    pass
+                    elems = parent.findall(elem.tag)
+                    try:
+                        cache[key] = elems[index]
+                    except IndexError:
+                        cache[key] = None
+                if cache[key] is elem:
+                    yield elem
         return select
     raise SyntaxError("invalid predicate")
# Source: https://github.com/python/cpython/commit/2ffab083782968a4d732738f4f1dff6bbd69d2b0

The patch introduces a per-invocation cache keyed by (parent, tag) so that the resolved indexed sibling is computed once per parent, reducing complexity from O(N²) to O(N).

Detection Methods for CVE-2026-6879

Indicators of Compromise

  • Sustained single-core CPU saturation in Python processes that parse XML from external sources.
  • Elevated request latency or timeouts on endpoints that call ElementTree.findall(), iterfind(), or find() with index predicates.
  • Inbound XML payloads containing unusually large counts of identical sibling tags.

Detection Strategies

  • Audit application code for uses of xml.etree.ElementTree combined with XPath expressions containing [N], [last()], or [last()-N].
  • Instrument XML parsing paths with per-request CPU-time and wall-clock timers to surface anomalous processing durations.
  • Add size and sibling-count limits to XML validators before invoking XPath selectors.

Monitoring Recommendations

  • Track Python process CPU utilization and correlate spikes with XML ingestion endpoints.
  • Log the byte size and element count of inbound XML documents accepted by application boundaries.
  • Alert on repeated requests from a single source that trigger long-running XML processing.

How to Mitigate CVE-2026-6879

Immediate Actions Required

  • Apply the upstream CPython fix from pull request gh-152676 once available in your Python release channel.
  • Enforce input size limits and maximum child-element counts on XML documents received from untrusted sources.
  • Where feasible, replace numeric XPath index predicates with iteration bounded by input validation.

Patch Information

The upstream fix is committed to CPython as commit 2ffab083, tracked in issue gh-152674 and merged via pull request gh-152676. Distribution details are provided in the Python Security Announcement.

Workarounds

  • Avoid [last()] and [last()-N] predicates on elements with unbounded sibling counts; select the last element in Python after a single findall() call.
  • Wrap XML parsing in a timeout or subprocess with a CPU-time limit to bound worst-case processing.
  • Pre-validate untrusted XML with a schema or lightweight parser that rejects excessive sibling counts before dispatching to ElementTree.
bash
# Configuration example: bound Python CPU time to contain quadratic parsing
python3 -c "import resource; resource.setrlimit(resource.RLIMIT_CPU, (5, 5))" \
  && python3 process_xml.py input.xml

Disclaimer: This content was generated using AI. While we strive for accuracy, please verify critical information with official sources.

Default Legacy - Prefooter | Experience the World’s Most Advanced Cybersecurity Platform

Experience the Most Advanced Cybersecurity Platform

See how the world’s most intelligent, autonomous cybersecurity platform can protect your organization today and into the future.