Skip to main content

Expat 2.8.1 released, CVE-2026-45186 and CVSS unreliability

For readers new to Expat:

libexpat is a fast streaming XML parser. Alongside libxml2, Expat is one of the most widely used software libre XML parsers written in C, specifically C99. It is cross-platform and licensed under the MIT license.

Expat 2.8.1 was released yesterday. The key motivation for cutting a release and doing so now was:

The vulnerability was reported to me responsibly about eight months ago by Nick Wellnhofer, the long-time and past maintainer of libxml2.

The attack relies on Expat <2.8.1 using an O(n²) runtime algorithm — a for loop — to check for collisions among attribute names. It takes nothing more than dialing up XML document…

<!DOCTYPE d [
  <!ATTLIST e a0 CDATA "" a1 CDATA "" a2 CDATA "">
]>
<d/>

…from 3 attributes to a number big enough for the specific target of the attack.

It should be noted that a layer of compression around XML can significantly reduce the minimum attack payload size.

There is an attack payload generator available for download: please use it responsibly!

Berkay Eren Ürün and I teamed up for a fix. It uses a hash table instead of a linear loop to detect collisions, which turns overall runtime from O(n*n) into O(n).

For some numbers (from older ThinkPad X220 hardware):

Count Runtime unfixed Runtime fixed Payload size
  (seconds) (seconds) (uncompressed, bytes)
10,000 0.17 0.03 135,615
100,000 13.22 0.24 1,395,615
200,000 59.71 0.49 2,795,615
400,000 253.18 1.04 5,708,119

And a quick graph:

It is worth noting that after I filed a CVE request with Mitre, someone turned my classification as remote (i.e. parsing from the wire) to mistaken local (i.e. local account access needed) and also to "Attack complexity: High" when it is a simple as shown above and with an attack payload generator being public. That results is a current CVSS score "2.9 of 10: LOW" on GitHub

…and also in NVD. I have requested a fix from Mitre in the mean time, but that's not fixing the core issue. This could serve as both a concrete example and a reminder that:

  • CVSS scores are unreliable: they are often over- or (worse) underestimating risk.

  • CVSS scores (and CVE reports) are edited by individuals that may or may not know better than the reporting individuals and/or the maintainers upstream.

  • CVSS score is not a metric to base decisions about vulnerabilities on.

Thanks to everyone who contributed to this release of Expat!

For more details about this release, please check out the change log.

If you maintain Expat packaging, a bundled copy of Expat, or a pinned version of Expat, please update to version 2.8.1. Thank you!

Sebastian Pipping