libxml2 is one of the most widely used XML parsing libraries on Linux and other platforms. It’s used by many popular applications, programming languages, and frameworks. On November 23, 2022, security researchers disclosed CVE-2022-49043, a critical _use-after-free_ vulnerability in libxml2, specifically in the function xmlXIncludeAddNode in xinclude.c, before version 2.11.. This flaw could allow attackers to crash applications or potentially execute code by manipulating XML files.

In this post, I'll explain what this vulnerability is, show the vulnerable code, and provide a simplified exploit demonstration.

What Is a Use-After-Free Vulnerability?

A use-after-free happens when a program continues to use a pointer to memory after it has been freed. This presents a golden opportunity for attackers:

The Root Cause: xmlXIncludeAddNode in libxml2

The problem occurs in the XInclude processing in libxml2. When a node is included, the code may inadvertently free the memory of the node, then use the dangling pointer later—triggering a use-after-free.

Vulnerable Code Snippet

Here’s an extracted and simplified version of the code from xinclude.c:

if (delete) {
    xmlFreeNode(cur->node);
    cur->node = NULL;
}

/* Later, cur->node is used again without checking */
if (cur->node) {
    /* Further operations */
}

If cur->node has been freed (and possibly set to NULL), but is used elsewhere, attackers can trigger a crash or worse if they control the input XML.

Official references

- National Vulnerability Database (NVD): CVE-2022-49043
- libxml2 commit fixing the bug
- libxml2 2.11. Release Notes

Force libxml2 to process it, causing the code path where the freed node is referenced.

3. Optionally spray memory with controlled data so that when the pointer is dereferenced, it’s pointing to attacker-chosen content.

Exploit Example

Below is a conceptual example in C. Suppose you have an application using libxml2’s XInclude support:

#include <libxml/parser.h>
#include <libxml/xinclude.h>

int main(int argc, char **argv) {
    xmlDocPtr doc;
    xmlInitParser();
    
    doc = xmlReadFile(argv[1], NULL, XML_PARSE_XINCLUDE);
    if (doc == NULL) {
        fprintf(stderr, "Failed to parse %s\n", argv[1]);
        return 1;
    }
    
    xmlXIncludeProcess(doc);
    xmlFreeDoc(doc);
    xmlCleanupParser();
    return ;
}

A malicious XML could be crafted with recursive or cyclic XInclude statements, causing the vulnerable function to trigger the bug.

Example malicious XML payload

<?xml version="1."?>
<root xmlns:xi="http://www.w3.org/2001/XInclude">;
  <xi:include href="payload.xml"/>
</root>

Suppose payload.xml is a huge file or contains more includes, it might overlap the memory and create conditions leading to the use-after-free.

Note: Crafting a reliable remote code execution exploit requires heap-feng-shui and deeper internals knowledge. In most real products, this bug is a Denial of Service until other bugs are combined.

Run this command

xml2-config --version

or, from Python

import lxml.etree
print(lxml.etree.LIBXML_VERSION)

Conclusion

CVE-2022-49043 is a textbook example of how memory management bugs in core libraries can have big impacts. If you use or distribute software that parses XML with libxml2, patch immediately.

For further reading

- libxml2 Security Issues
- CVE Details for libxml2

Keep your dependencies up to date, stay safe, and always sanitize inputs when dealing with external data!


*This article is original and written in simple terms. If you have questions, reach out!*

- CVE-2022-49043 on NVD
- libxml2 Source Code Fix
- libxml2 Release 2.11.

Timeline

Published on: 01/26/2025 06:15:21 UTC