On January 13, 2022, a critical security vulnerability (CVE-2022-22827) was disclosed in Expat, also known as libexpat, a widely-used XML parsing library written in C. The vulnerability, found in versions before 2.4.3, is an integer overflow in the storeAtts function inside the xmlparse.c source file. This post breaks down the bug, presents code snippets, explains exploit potential, and provides security recommendations—all in straightforward language.

What is Expat (libexpat)?

Expat is an open-source XML parser library written in C, commonly embedded in countless software projects. Many programming languages (such as Python and Perl), software packages, and devices use Expat for parsing XML. Its popularity and widespread use make any security issue particularly concerning.

Official Advisory

- NVD CVE-2022-22827 Entry
- Expat Security Release 2.4.3

Root Cause

The vulnerable function, storeAtts, is responsible for storing XML attributes during parsing. It computes the total number of attribute pointers without sufficient checks for integer overflows. If provided with a malicious XML file containing a huge number of attributes, the integer arithmetic may overflow, leading to a buffer smaller than needed, and resulting in a write out-of-bounds.

This code is from the old xmlparse.c, simplified to show the vulnerability

int n = nAttributes * 2;
ATTRIBUTE *temp = REALLOC(attributes, n * sizeof(ATTRIBUTE));
if (temp == NULL) {
    // handle allocation error
}
attributes = temp;

What's wrong?

- If nAttributes is very large, n * sizeof(ATTRIBUTE) can wrap around (overflow), allocating less memory than needed.

Exploitable Scenario

1. Crafted XML: Attacker sends an XML document with an excessive number of attributes on a single element.
2. Overflow Triggered: Arithmetic for allocation wraps, e.g., if sizeof(ATTRIBUTE) == 16 and nAttributes == x10000000, the result might become a small value, not enough for the actual attributes.
3. Memory Corruption: Attributes are stored past allocated buffer, overwriting memory, possibly allowing code execution, or at minimum, denial of service (crash).

Example of Malicious XML

<element 
    a1="v1" a2="v2" a3="v3" 
    ... 
    a10000000="v10000000">
</element>

*(Ellipsis indicates a very high number of attributes to trigger overflow)*

How would an attacker use this vulnerability?

- Remote Code Execution: By controlling and corrupting process memory, attackers may inject and run arbitrary code, especially if parsing is done with elevated privileges.
- Denial of Service (Crash): Even if not directly exploitable, crashing the parsing process may be enough to cause service outages (DoS).
- Supply Chain Impact: Any software embedding vulnerable Expat is at risk, including desktop and server software, networking equipment, and IoT devices.

The XML includes a vast number of attributes to an element.

3. The allocator is tricked, and the parser overflows, causing a crash or opening a code execution path.

*(A full weaponized exploit is not shown for ethical reasons, but the above is sufficient to demonstrate risk.)*

How Was It Fixed?

The patch introduced arithmetic checks to prevent integer overflow before allocating memory. Here's a simplified patch snippet:

/* Check before allocation */
if (nAttributes > INT_MAX / (2 * sizeof(ATTRIBUTE))) {
    /* fail gracefully */
}
int n = nAttributes * 2;
ATTRIBUTE *temp = REALLOC(attributes, n * sizeof(ATTRIBUTE));

This ensures n * sizeof(ATTRIBUTE) cannot overflow int limits, thus preventing dangerous allocations.

Reference:

- Github commit fixing the bug

You use Expat (libexpat) version before 2.4.3 in your code or dependencies.

- Your application accepts and parses untrusted XML—for example, files uploaded by users, data fetched via APIs, configurations, etc.

Upgrade to libexpat 2.4.3 or newer.

Download Expat latest versions

Patch Your Project:

Ensure any applications or libraries that statically include old versions of Expat are rebuilt against the fixed version.

Conclusion

CVE-2022-22827 is a critical lesson that "just XML" parsing isn't always safe. An integer overflow in Expat's storeAtts function could allow malicious XML files to crash or compromise your system. Patch your systems, update your dependencies, and be wary of XML input from unknown sources.

References

- CVE-2022-22827 at NIST NVD
- Red Hat Security Advisory
- libexpat Security Release Notes
- Patch commit

*(All information is provided for defensive purposes. Always apply security patches promptly!)*

Timeline

Published on: 01/10/2022 14:12:00 UTC
Last modified on: 06/14/2022 11:15:00 UTC