Safeguard
Vulnerability Analysis•

Expat 2.9.0 and Debian DSA-6566-1: Six XML Parser CVEs in Two Months

Debian's 16 Oct 2026 expat update rolls up fixes from Expat 2.8.4, 2.8.5 and 2.9.0. Expat hides inside Python, Git, Apache and more, so inventory it.

Safeguard Security Team
4 min read

On 16 October 2026 Debian published DSA-6566-1, an update for the expat XML parsing library on Debian 13 (trixie). It fixes six CVEs and moves the package to 2.9.0-1~deb13u1. Upstream shipped the underlying fixes across three releases: Expat 2.8.4 on 31 August, 2.8.5 on 22 September and 2.9.0 on 5 October.

Expat is a library most teams never chose directly. It arrives through Python's pyexpat, Git, Apache, Subversion, Firefox, many language runtimes and countless container images.

What's affected

Debian's advisory lists CVE-2026-66046, CVE-2026-76956, CVE-2026-76957, CVE-2026-77214, CVE-2026-93990 and CVE-2026-102633. The upstream Changes file and the CVE records give the details:

Upstream releaseCVEIssue
2.8.4 (31 Aug)CVE-2026-66046Quadratic runtime in storeAtts() from attribute lookups. A few megabytes of well-formed XML can burn CPU. Needs no authentication or special parser options.
2.8.4CVE-2026-76956Inverted getentropy() return handling in 2.8.2 and 2.8.3 weakens hash salt, enabling hash flooding denial of service.
2.8.4CVE-2026-76957No depth tracking for custom encoding callbacks, so a use-after-free can occur.
2.8.5 (22 Sep)CVE-2026-93990UTF-16 high surrogate not checked for a following low surrogate, so malformed input is accepted. Upstream lists a 9.8 CVSS 3.1 score.
2.9.0 (5 Oct)CVE-2026-77214XML_ParseBuffer does not validate len against buffer capacity, allowing a heap over-read.
2.9.0CVE-2026-102633Integer overflow in expat_realloc() on 32-bit platforms.

CVE-2026-102633 only applies to 32-bit builds. CVE-2026-77214 only applies to programs that call XML_GetBuffer and XML_ParseBuffer directly.

Expat 2.9.0 also removes XML_GetAttributeInfo and the XML_MIN_SIZE feature, bumps the shared library to libexpat.so.1.13.0, and deprecates XML_LARGE_SIZE. If you build Expat from source, expect build failures where you use those options.

How to check if you're exposed

dpkg-query -W libexpat1
python3 -c "import pyexpat; print(pyexpat.EXPAT_VERSION)"
ldd $(command -v git) | grep -i expat

Python reports the Expat version it was linked against. Some Python builds statically bundle Expat, in which case the system package does not help and you need a new Python build.

For container fleets, search every image for the library file:

docker run --rm --entrypoint sh myorg/api:latest -c 'ls /usr/lib/*/libexpat.so* 2>/dev/null; dpkg-query -W libexpat1 2>/dev/null'

What to do now

  1. On Debian 13: sudo apt update && sudo apt install --only-upgrade libexpat1, and confirm 2.9.0-1~deb13u1.
  2. On other distributions, look up each CVE ID in your vendor tracker. Debian's fix version number says nothing about a RHEL or Alpine backport.
  3. Rebuild images based on Debian trixie and re-run the check above on the new digest.
  4. For vendored or statically linked copies, search your SBOMs for expat and libexpat and schedule a rebuild of every product that embeds a version below 2.9.0.
  5. Treat any service that parses untrusted XML from the internet, such as SOAP endpoints, SAML, SVG or Office upload handlers, as first in line.

Why it matters

Three upstream releases in about five weeks is a busy cadence for a parser that was quiet for long stretches. Each version fixes issues in a different layer: algorithmic cost, memory safety and encoding validation. That is a reminder that XML parsing keeps producing bugs even in mature code.

The practical problem is inventory, not patching. The library is easy to update where the distro owns it and hard where it is embedded. An SBOM turns that into a search.

Try it yourself

Take one service's lockfile or SBOM and look for expat or a package that bundles it, then note which version it pins.

Click through it at your own pace, or open it full screen.

Quick check

Which upstream Expat version contains all six fixes?

Expat 2.9.0, released on 5 October 2026. Debian's package 2.9.0-1~deb13u1 tracks it.

Why does updating libexpat1 not always fix Python?

Some Python builds bundle their own Expat. Check pyexpat.EXPAT_VERSION and update Python itself in that case.

Sources

Never miss an update

Weekly insights on software supply chain security, delivered to your inbox.

Self-healing security runs on Safeguard.

Your first fix PR is minutes away.

No sales call required, even your agent can complete the purchase over MCP.