CVE-2026-4224
High · 7.5CVSS
7.5
EPSS
0.7%
Published
Mar 16, 2026
CISA due date
—
Cloudanix analysis
A specially crafted XML file can crash some Python-based services that process XML, potentially making those services unavailable.
- Exploitation
- Remote Authenticated
- Attacker needs
- Low Privilege
- Complexity
- Moderate
- Impact
- Denial Of Service
- Component
- Library
- Class
- Denial of service
- Remediation
- Upgrade
- Effort
- Medium
- Patch risk
- Low
What it actually does
This vulnerability can cause a C stack overflow in the Expat XML parser when an application has registered an ElementDeclHandler and parses an inline document type definition containing a deeply nested content model. In affected Python deployments that expose Expat-based XML parsing to untrusted input, a crafted XML document can crash the parsing process, resulting in denial of service. The issue impacts availability rather than confidentiality or integrity.
Why it matters to the business
Applications, APIs, data ingestion pipelines, or backend services that parse user-supplied XML may become unavailable if an attacker submits a malicious XML document. The risk is highest for internet-facing or multi-tenant services that accept XML uploads, API payloads, SAML-like XML, SOAP messages, document conversions, or feed ingestion. Current public exploitation signals are low: EPSS is approximately 0.0064 with no 30-day increase, no known CISA KEV listing, no known ransomware association, and no reported exploit maturity in the provided data. However, because Python and Expat are widely embedded in applications and downstream products, exposure may be broader than direct package inventory suggests.
How an attack unfolds
An attacker first identifies an application path that accepts XML and processes it using Python components backed by Expat. Exploitation requires the parser path to have an ElementDeclHandler registered and to allow inline DTD processing. The attacker then submits a specially crafted XML document containing an inline DOCTYPE with an excessively deep nested content model in an element declaration. During parsing, Expat recursively processes the nested content model and exhausts the C stack, causing the process to crash. If the affected parser runs inside a web worker, API service, batch processor, or message consumer, repeated submissions can cause sustained service disruption until input validation, parser hardening, process isolation, or package fixes are applied.
How to fix it
Upgrade affected Python and Expat components when vendor-fixed versions are available for the operating system, Python distribution, container image, or application runtime in use. No exact fixed versions were provided in the input, so remediation should be tracked against the relevant Python, libexpat, OS distribution, and application vendor advisories. As compensating controls, disable inline DTD processing for untrusted XML where possible, reject XML documents containing DOCTYPE or ELEMENT declarations unless explicitly required, avoid registering ElementDeclHandler for untrusted content, enforce strict XML payload size and nesting limits, run XML parsing in isolated worker processes with restart controls, and apply request rate limiting to XML-processing endpoints. Rebuild and redeploy containers or statically linked applications that bundle vulnerable Expat copies rather than relying only on host package updates.
How to confirm the fix worked
Confirm exposure by inventorying applications and containers that use Python XML parsing backed by Expat, including xml.parsers.expat, pyexpat, SAX handlers, and third-party libraries that wrap Expat. Review whether any parser registers ElementDeclHandler and whether untrusted XML with inline DTDs is accepted. Validate remediation by confirming upgraded Python/libexpat package versions from the relevant vendor advisory, rebuilding container images, and verifying that applications reject or safely ignore inline DOCTYPE and ELEMENT declarations from untrusted sources. In a controlled non-production environment, use a benign deeply nested DTD test case to confirm the parser no longer crashes and that service workers remain healthy. Monitor for absence of new parser-related segmentation faults or crash loops after deployment.
Typical attack path
- Find an endpoint, upload workflow, API, message queue, or ingestion service that accepts XML input.
- Confirm that the XML parser permits inline DTD declarations and routes parsing through Expat-backed Python XML handling.
- Submit XML containing an inline DOCTYPE and deeply nested element content model.
- Trigger a C stack overflow during Expat parsing when the ElementDeclHandler processes the nested content model.
- Cause the parsing process or hosting worker to terminate unexpectedly.
- Repeat requests or messages to keep the service degraded or unavailable.
How to detect it
To determine whether exploitation already occurred, review application logs, web access logs, API gateway logs, message broker payload metadata, worker supervisor logs, container runtime events, kernel logs, and crash reporting systems around XML-processing services. Look for requests or messages containing inline DOCTYPE and ELEMENT declarations, especially with unusually deep nested parentheses in a DTD content model, followed by process termination, segmentation faults, worker restarts, container restarts, HTTP 500/502/503 responses, queue retries, or ingestion failures. On Linux systems, inspect syslog, journald, dmesg, kernel audit logs, coredumpctl, systemd unit logs, Kubernetes pod restart events, and application performance monitoring crash traces for Python or Expat-related crashes. Correlate suspicious XML submissions with the same source IP, account, API token, partner connection, or message producer repeatedly causing parser crashes. There are no known named threat actors, KEV exploitation, or ransomware campaigns in the provided data, so detection should focus on crash artifacts and malicious XML structure rather than actor-specific infrastructure.
- <!DOCTYPE
- <!ELEMENT
- <!ATTLIST
- xml.parsers.expat
- pyexpat
- ElementDeclHandler
- Segmentation fault
- segfault
- core dumped
- Fatal Python error
- Process exited with signal 11
- signal 11
- SIGSEGV
- CrashLoopBackOff
- Back-off restarting failed container
- OOMKilled=false
- DOCTYPE.*<!ELEMENT
- <!ELEMENT.*\(\(\(
- <!ELEMENT.*\)\)\)
What your security team should do
- Prioritize internet-facing and partner-facing services that accept XML uploads, SOAP/XML APIs, feeds, document imports, or message-based XML ingestion.
- Create an inventory of Python applications and packaged products that use Expat, pyexpat, xml.parsers.expat, SAX, or XML libraries that may delegate to Expat.
- Track vendor advisories for Python, libexpat, operating system packages, container base images, and embedded products; upgrade as soon as fixed builds are available.
- Temporarily block or reject inline DTDs, DOCTYPE declarations, and ELEMENT declarations from untrusted XML inputs where business functionality allows.
- Add payload size, recursion, and nesting-depth limits around XML parsing and run parsing workloads in isolated, auto-restarted workers.
- Add monitoring for crashes, segmentation faults, worker restarts, HTTP 5xx spikes, queue reprocessing loops, and repeated XML parse failures.
- Because EPSS is low, no KEV listing is present, and no exploit maturity is reported, handle as a targeted availability risk rather than an active mass-exploitation emergency unless local exposure is high.
The record
When an Expat parser with a registered ElementDeclHandler parses an inline document type definition containing a deeply nested content model a C stack overflow occurs.
Affected packages
| Ecosystem | Package | Introduced | Fixed |
|---|---|---|---|
| Chainguard | python-3.13 | 0 | 3.13.12-r7 |
| Chainguard | python-3.14 | 0 | 3.14.3-r6 |
| SUSE:Linux Enterprise High Performance Computing 15 SP4-ESPOS | python310 | 0 | 3.10.20-150400.4.107.1 |
| SUSE:Linux Enterprise High Performance Computing 15 SP4-ESPOS | python310-core | 0 | 3.10.20-150400.4.107.1 |
| SUSE:Linux Enterprise High Performance Computing 15 SP4-LTSS | python310 | 0 | 3.10.20-150400.4.107.1 |
| SUSE:Linux Enterprise High Performance Computing 15 SP4-LTSS | python310-core | 0 | 3.10.20-150400.4.107.1 |
| SUSE:Linux Enterprise Module for Basesystem 15 SP7 | python311-core | 0 | 3.11.15-150600.3.53.1 |
| SUSE:Linux Enterprise Module for Package Hub 15 SP7 | python | 0 | 2.7.18-150000.111.1 |
| SUSE:Linux Enterprise Module for Package Hub 15 SP7 | python-base | 0 | 2.7.18-150000.111.1 |
| SUSE:Linux Enterprise Module for Python 3 15 SP7 | python311 | 0 | 3.11.15-150600.3.53.1 |
| SUSE:Linux Enterprise Module for Python 3 15 SP7 | python311-core | 0 | 3.11.15-150600.3.53.1 |
| SUSE:Linux Enterprise Server 15 SP4-LTSS | python310 | 0 | 3.10.20-150400.4.107.1 |
| SUSE:Linux Enterprise Server 15 SP4-LTSS | python310-core | 0 | 3.10.20-150400.4.107.1 |
| SUSE:Linux Enterprise Server 15 SP5-LTSS | python39 | 0 | 3.9.25-150300.4.99.1 |
| SUSE:Linux Enterprise Server 15 SP5-LTSS | python39-core | 0 | 3.9.25-150300.4.99.1 |
| SUSE:Linux Enterprise Server 15 SP6-LTSS | python311 | 0 | 3.11.15-150600.3.53.1 |
| SUSE:Linux Enterprise Server 15 SP6-LTSS | python311-core | 0 | 3.11.15-150600.3.53.1 |
| SUSE:Linux Enterprise Server 15 SP6-LTSS | python312 | 0 | 3.12.13-150600.3.53.1 |
| SUSE:Linux Enterprise Server 15 SP6-LTSS | python312-core | 0 | 3.12.13-150600.3.53.1 |
| SUSE:Linux Enterprise Server for SAP Applications 15 SP4 | python310 | 0 | 3.10.20-150400.4.107.1 |
| SUSE:Linux Enterprise Server for SAP Applications 15 SP4 | python310-core | 0 | 3.10.20-150400.4.107.1 |
| SUSE:Linux Enterprise Server for SAP Applications 15 SP5 | python39 | 0 | 3.9.25-150300.4.99.1 |
| SUSE:Linux Enterprise Server for SAP Applications 15 SP5 | python39-core | 0 | 3.9.25-150300.4.99.1 |
| SUSE:Linux Enterprise Server for SAP Applications 15 SP6 | python311 | 0 | 3.11.15-150600.3.53.1 |
| SUSE:Linux Enterprise Server for SAP Applications 15 SP6 | python311-core | 0 | 3.11.15-150600.3.53.1 |
| SUSE:Linux Enterprise Server for SAP Applications 15 SP6 | python312 | 0 | 3.12.13-150600.3.53.1 |
| SUSE:Linux Enterprise Server for SAP Applications 15 SP6 | python312-core | 0 | 3.12.13-150600.3.53.1 |
| Wolfi | python-3.13 | 0 | 3.13.12-r7 |
| Wolfi | python-3.14 | 0 | 3.14.3-r6 |
| openSUSE:Leap 15.6 | python | 0 | 2.7.18-150000.111.1 |
| openSUSE:Leap 15.6 | python-base | 0 | 2.7.18-150000.111.1 |
| openSUSE:Leap 15.6 | python-doc | 0 | 2.7.18-150000.111.1 |
| openSUSE:Leap 15.6 | python310 | 0 | 3.10.20-150400.4.107.1 |
| openSUSE:Leap 15.6 | python310-core | 0 | 3.10.20-150400.4.107.1 |
| openSUSE:Leap 15.6 | python310-documentation | 0 | 3.10.20-150400.4.107.1 |
| openSUSE:Leap 15.6 | python311 | 0 | 3.11.15-150600.3.53.1 |
| openSUSE:Leap 15.6 | python311-core | 0 | 3.11.15-150600.3.53.1 |
| openSUSE:Leap 15.6 | python311-documentation | 0 | 3.11.15-150600.3.53.1 |
| openSUSE:Leap 15.6 | python312 | 0 | 3.12.13-150600.3.53.1 |
| openSUSE:Leap 15.6 | python312-core | 0 | 3.12.13-150600.3.53.1 |
| openSUSE:Leap 15.6 | python312-documentation | 0 | 3.12.13-150600.3.53.1 |
| openSUSE:Leap 15.6 | python39 | 0 | 3.9.25-150300.4.99.1 |
| openSUSE:Leap 15.6 | python39-core | 0 | 3.9.25-150300.4.99.1 |
| openSUSE:Leap 15.6 | python39-documentation | 0 | 3.9.25-150300.4.99.1 |
| openSUSE:Leap 16.0 | python313 | 0 | 3.13.13-160000.1.1 |
| openSUSE:Leap 16.0 | python313-core | 0 | 3.13.13-160000.1.1 |
| openSUSE:Leap 16.0 | python313-documentation | 0 | 3.13.13-160000.1.1 |
| openSUSE:Leap 16.0 | python313-nogil | 0 | 3.13.13-160000.1.1 |
| openSUSE:Leap 16.0 | python313-nogil-nogil-core | 0 | 3.13.13-160000.1.1 |
| openSUSE:Tumbleweed | python310 | 0 | 3.10.20-3.1 |
| openSUSE:Tumbleweed | python311 | 0 | 3.11.15-4.1 |
| openSUSE:Tumbleweed | python312 | 0 | 3.12.13-4.1 |
| openSUSE:Tumbleweed | python313 | 0 | 3.13.12-3.1 |
| openSUSE:Tumbleweed | python314 | 0 | 3.14.3-4.1 |
| openSUSE:Tumbleweed | python315 | 0 | 3.15.0~a7-3.1 |
Related vulnerabilities
- CVE-2026-4519 The webbrowser.open() API would accept leading dashes in the URL which could be handled… Also affects python-3.13
- CVE-2026-3644 The fix for CVE-2026-0672, which rejected control characters in http.cookies.Morsel, was… Also affects python-3.13
- CVE-2026-2297 The import hook in CPython that handles legacy *.pyc files (SourcelessFileLoader) is… Also affects python-3.13
- CVE-2026-1299 The email module, specifically the "BytesGenerator" class, didn’t properly quote newlines… Also affects python-3.13
- CVE-2026-0672 When using http.cookies.Morsel, user-controlled cookie values and parameters can allow… Also affects python-3.13
- CVE-2026-0865 User-controlled header names and values containing newlines can allow injecting HTTP… Also affects python-3.13
- CVE-2025-11468 When folding a long comment in an email header containing exclusively unfoldable… Also affects python-3.13
- CVE-2025-15282 User-controlled data URLs parsed by urllib.request.DataHandler allow injecting headers… Also affects python-3.13