See how expat compares to other vendors in security performance
libexpat before 2.8.2 does not consider XMLTOKDATACHARS in doCdataSection and thus lacks handler call depth tracking for various calls from within handlers in cases of a policy violation. Thus, a use-after-free can occur. NOTE: this issue exists because of an incomplete fix for CVE-2026-50219.
xmlwf in libexpat before 2.8.2 has an integer overflow in endDoctypeDecl via NOTATION declarations.
xmlwf in libexpat before 2.8.2 has an integer overflow in resolveSystemId.
xmlwf in libexpat before 2.8.2 has an integer overflow for the output filename when -d outputDir is used.
libexpat before 2.8.2 has an integer overflow in copyString.
libexpat before 2.8.2 has an integer overflow in doProlog that is related to storeEntityValue and entity textLen.
libexpat before 2.8.2 has an integer overflow in XMLParseBuffer because it lacked a check that was present in XMLParse.
libexpat before 2.8.2 has an integer overflow in getAttributeId.
libexpat before 2.8.2 has an integer overflow in addBinding.
libexpat before 2.8.2 has an integer overflow in storeAtts.
In libexpat before 2.8.2, there is a heap-based buffer overflow in doProlog in xmlparse.c because scaffold backing array reallocation is mishandled when there is data-structure sharing across parsers.
libexpat before 2.8.2 lacks handler call depth tracking for calls to XMLResumeParser from within handlers in cases of a policy violation. Thus, a use-after-free can occur (similar to the CVE-2026-50219 situation).
libexpat before 2.8.2 lacks handler call depth tracking for calls to XMLGetBuffer, XMLParse, XMLParseBuffer, XMLParserFree, or XMLParserReset from within handlers in cases of a policy violation. Thus, a use-after-free can occur,
Hello oss-security,
just a quick note that libexpat 2.8.1 (or "Expat 2.8.1") released yesterday is fixing CVE-2026-45186:
Fix quadratic runtime from attribute name collision checks that allowed denial of service attacks through moderately sized crafted XML input (CWE-407). Please note that a layer of compression around XML can significantly reduce the minimum attack payload size.
Some key links are:
- The blog post about it https://blog.hartwork.org/posts/expat-2-8-1-released/
- The change log of release 2.8.1 https://github.com/libexpat/libexpat/blob/R281/expat/Changes
- The fixing pull request https://github.com/libexpat/libexpat/pull/1216
- The NVD CVE metadata https://nvd.nist.gov/vuln/detail/CVE-2026-45186
PS: The CVE database lists an unrealistically low CVSS score for this. The complexity of an attack is very low (not "High") and the attack vector is remote (not "Local"). I have asked Mitre to fix this earlier today. My blog post linked above has a few more words on that topic.
Best
Sebastian
xml.parsers.expat and xml.etree.ElementTree use insufficient entropy for Expat hash-flooding protection, which allows a crafted XML document to trigger hash flooding.\r\n\r\nFully mitigating this vulnerability requires both updating libexpat to 2.8.0 or later and applying this patch.
In libexpat before 2.8.1, the computational complexity of attribute name collision checks allows a denial of service via moderately sized crafted XML input.
In libexpat before 2.8.1, the computational complexity of attribute name collision checks allows a denial of service via moderately sized crafted XML input.
Hello oss-security,
just a quick note that libexpat 2.8.0 (or "Expat 2.8.0") released two days ago is fixing CVE-2026-41080.
Some key links are:
- The blog post about it https://blog.hartwork.org/posts/expat-2-8-0-released/
- The change log of release 2.8.0 https://github.com/libexpat/libexpat/blob/R280/expat/Changes
- The fixing pull request https://github.com/libexpat/libexpat/pull/1183
- The official CVE metadata https://nvd.nist.gov/vuln/detail/CVE-2026-41080
Best
Sebastian
libexpat before 2.8.0 uses insufficient entropy, and thus hash flooding can occur via a crafted XML document.
Hello oss-security,
just a quick note that libexpat 2.7.5 (or "Expat 2.7.5") released today is fixing three vulnerabilities.
Some key links are:
- The blog post about it: https://blog.hartwork.org/posts/expat-2-7-5-released/
- The change log of release 2.7.5 https://github.com/libexpat/libexpat/blob/R275/expat/Changes
- The fixing pull requests - https://github.com/libexpat/libexpat/pull/1158 - https://github.com/libexpat/libexpat/pull/1162 - https://github.com/libexpat/libexpat/pull/1163
- The official CVE metadata - https://nvd.nist.gov/vuln/detail/CVE-2026-32776 - https://nvd.nist.gov/vuln/detail/CVE-2026-32777 - https://nvd.nist.gov/vuln/detail/CVE-2026-32778
Best
Sebastian
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.
https://github.com/libexpat/libexpat/issues/1076 notes: Hi!
Just a quick note that there is another unfixed vulnerability in Expat on my desk by now:
- It's been reported on September 25th by a human (not fuzzing) - The impact is denial of service - To be more concrete: A crafted file of size ~2 MiB can cause 25–100 seconds processing time, depending on the used hardware.
My own priorities are elsewhere at the moment. Please reach out if:
- you want to help finding a true fix and - you are okay with signing a freeform NDA (to keep the vulnerability details confidential until a fix has made its way into Git master).
It's not going to be as complex as resolving recursion for Expat 2.7.0 but the path forward for a fix is not clear yet.
Best, Sebastian
PS: Comments are intentionally closed, please reach out via the e-mail in my profile, instead. [note that I'm just passing this along - if you want to help, contact Sebastian via the link to his profile from the github issue, not me.]
libexpat in Expat before 2.7.2 allows attackers to trigger large dynamic memory allocations via a small document that is submitted for parsing.
Accessibility. A privacy issue was addressed by removing sensitive data.
Hi Hanno, all,
On Fri, Mar 14, 2025 at 07:53:24PM +0100, Hanno Böck wrote: I believe from the above that current systems should not be vulnerable to this type of vulnerability. I am unsure about systems that do not apply -fstack-clash-protection. We have not looked into this specific expat vulnerability yet, and we have not tried to exploit a stack-clash vulnerability in a long time, but maybe what follows will be useful anyway.
The TL;DR is probably: stack-clash vulnerabilities are not exploitable for arbitrary code execution anymore, because (to the best of our knowledge) all major Linux distributions use -fstack-clash-protection nowadays; and even without -fstack-clash-protection, most of these vulnerabilities are not exploitable anymore thanks to the Linux kernel mitigation that was introduced in 2017 (a 1MB stackguardgap).
1/ Over the years we have disassembled various binaries in various Linux distributions, and it is clear that at least SUSE, Fedora, Ubuntu, Debian, and Red Hat Enterprise Linux 9 and derivatives compile everything (or at least everything security-sensitive) with -fstack-clash-protection, which makes it impossible to exploit such vulnerabilities for arbitrary code execution.
2/ Even without -fstack-clash-protection, such a vulnerability must satisfy two key (and unlikely) requirements to be exploitable:
- at least one single stack allocation must exceed 1MB to bridge the gap between the main stack and another memory region, because the kernel's stackguardgap was increased from a few kilobytes to 1MB in 2017 -- most likely this stack allocation must be a variable-length array or an unbounded alloca();
- this large stack allocation must not be fully written to, otherwise the stackguardgap is written to and causes a crash, not a memory corruption or code execution.
3/ The last kind of stack-clash vulnerability that we exploited was in 2019, in systemd-journald. It was exploitable because we could alloca() an array of up to 4GB, and we could prevent this array from being fully written to. But even in 2019, SUSE and Fedora were not exploitable because they were already using -fstack-clash-protection:
https://www.qualys.com/2019/01/09/system-down/system-down.txt From https://blog.hartwork.org/posts/expat-2-7-0-released/: Please leave recursion to math and keep it out of (in particular C) software: it kills and will kill again. :-) Also:
https://www.openwall.com/lists/oss-security/2025/03/15/1
Thank you very much! With best regards,
-- the Qualys Security Advisory team
Hello,
A vulnerability (CVE-2024-8176) has been fixed in expat, a widely used xml parser library: https://blog.hartwork.org/posts/expat-2-7-0-released/ Info about the vuln has been posted here already. expat 2.7.0 fixes multiple variations of stack overflows due to recursion and can be triggered by using a large number of nested entities. Scripts to generate example payloads for testing can be found in the project's issue tracker: https://github.com/libexpat/libexpat/issues/893
I had some discussions with the maintainer of expat before this was published about the security impact. We believe that this is likely, in most cases, "only" a crash/denial of service type of bug.
Here is what I believe to be the case:
Recursion stack overflow can lead to a stack clash, which might enable memory corruption and code execution. There has been some detailed investigation of this type of vulnerability by Qualys in 2017: https://blog.qualys.com/vulnerabilities-threat-research/2017/06/19/the-stack-clash https://www.qualys.com/2017/06/19/stack-clash/stack-clash.txt
As a response to this research, it was concluded that existing countermeasures for these types of vulnerabilities are insufficient, and a new compiler flag -fstack-clash-protection was introduced: https://developers.redhat.com/blog/2020/05/22/stack-clash-mitigation-in-gcc-part-3 The -fstack-clash-protection flag is available in recent versions of gcc and clang, and many distributions have it enabled by default. There also have been changes to glibc and the Linux kernel in response: https://bugzilla.redhat.com/showbug.cgi?id=CVE-2017-1000366 (glibc) https://bugzilla.redhat.com/showbug.cgi?id=CVE-2017-1000364 (Linux kernel)
I believe from the above that current systems should not be vulnerable to this type of vulnerability. I am unsure about systems that do not apply -fstack-clash-protection. My understanding of these types of vulnerabilities is limited, and by posting this here, I hope that people more familiar with it will have a closer look. I am also not sure how widely these mitigations have been applied and whether there are major distributions not using -fstack-clash-protection by default.
-- Hanno Böck - Independent security researcher https://itsec.hboeck.de/ https://badkeys.info/
On 3/15/24 09:57, Alan Coopersmith wrote: https://blog.hartwork.org/posts/expat-2-6-2-released/ (published 2024-03-13) announces the release of Expat 2.6.2, with security fixes: [...] The blog also points to the call for help maintaining libexpat in the Changelog at https://github.com/libexpat/libexpat/blob/R262/expat/Changes which notes that items that need someone to work on include:
!! - <blink>fixing a complex non-public security issue</blink>, !! Expat 2.7.0 has now been released with a fix for that issue, and the issue has been disclosed in: https://blog.hartwork.org/posts/expat-2-7-0-released/ https://github.com/libexpat/libexpat/issues/893 https://github.com/libexpat/libexpat/pull/973
Jann Horn of Google Project Zero is credited with reporting the issue, while Siemens is credited with making the fix, and Red Hat, Linutronix, and a company that would not like to be named, are credited for helping test the fix.
The short summary from the bug report:
A long linear chain of entity references: long enough to force the recursion in Expat into stack overflow.
How long the chain needs to be depends on the stack size of the target machine. To illustrate the structure:
# python3 payload1.py 2 <!DOCTYPE doc [ <!ENTITY e0 ''> <!ENTITY e1 '&e0;'> <!ENTITY e2 '&e1;'> ]> <doc>&e2;</doc>
# python3 payload2.py 2 <!DOCTYPE a [ <!ENTITY e0 ''> <!ENTITY e1 '&e0;'> <!ENTITY e2 '&e1;'> ]> <a key='&e2;'/>
# python3 payload3.py 2 <!DOCTYPE doc [ <!ENTITY % p0 ''> <!ENTITY % p1 '%p0;'> <!ENTITY % p2 '%p1;'> <!ENTITY % defineg0 "<!ENTITY g0 '%p2;'>"> %defineg0; ]> <doc/>
(The payload.py scripts are linked from https://github.com/libexpat/libexpat/issues/893)
The blog requests that "you please tell your friends:
Please leave recursion to math and keep it out of (in particular C) software: it kills and will kill again. Kind regards from libexpat, see CVE-2022-25313 and CVE-2024-8176 for proof."
-- -Alan Coopersmith- alan.coopersmith () oracle com Oracle Solaris Engineering - https://blogs.oracle.com/solaris
An issue was discovered in libexpat before 2.6.4. There is a crash within the XMLResumeParser function because XMLStopParser can stop/suspend an unstarted parser.
A stack overflow vulnerability exists in the libexpat library due to the way it handles recursive entity expansion in XML documents. When parsing an XML document with deeply nested entity references, libexpat can be forced to recurse indefinitely, exhausting the stack space and causing a crash. This issue could lead to denial of service (DoS) or, in some cases, exploitable memory corruption, depending on the environment and library usage.
The libexpat library is vulnerable to a stack overflow due to uncontrolled recursion when processing deeply nested XML entities. This can cause the application to crash, resulting in a denial of service (DoS) or potentially leading to memory corruption, depending on the user's environment and how the library is used. The issue is triggered by supplying a specially crafted XML document designed to create a long chain of recursive entities.