psf-expat-check(8)

Script: /opt/psf-security-patches/expat/expat-check.sh. Tool page: libexpat. Source. With the package installed: man psf-expat-check.

libexpat billion laughs detection delay: read-only checker  (v1)
CVE-2026-115506

If this software is helpful, consider a donation to our 501c3 nonprofit:
https://privacysafe.foundation

libexpat is the XML parser inside Python (pyexpat), Apache httpd, many PHP and
Perl builds, Subversion, Mercurial, D-Bus, fontconfig, Firefox and a very long
list of other programs. Its protection against "billion laughs" entity
amplification works by tracking how much a parse expands. In
accountingDiffTolerated() in xmlparse.c that check detects the amplification
too late, so a moderately sized crafted XML document can still make the parser
consume a large amount of CPU and memory before the protection stops it. The
result is denial of service. Rated High (CVSS 7.5 v3; the CVE list shows 8.7 on
the v4 scale). No authentication is needed wherever a service parses XML from
an untrusted source. Reported through Google; the upstream issue is #1160.

  Affected: libexpat through 2.9.0, that is every release so far
  Fix:      merged upstream on 23 October 2026 (pull request #1433) and
            milestoned for Expat 2.9.1

Install Expat 2.9.1 or later when it reaches you: upstream attached the fix to
that milestone. The script reports every copy at 2.9.0 or older as affected and
2.9.1 or newer as fixed. Distribution
packages usually backport fixes without changing the version, which the
script checks for.

This script is read-only. It finds libexpat shared libraries, reads the version
string compiled into each, asks installed Python interpreters for
pyexpat.EXPAT_VERSION, lists running processes that have libexpat mapped
(and flags those still running a replaced copy), and can scan directories for
programs that carry their own copy.

Usage:
  ./expat-check.sh [command] [DIR ...]

  check (default)  system libraries, Python interpreters and running processes.
                   Exit 0 = every copy found is fixed, 1 = an affected copy found.
  deep [DIR ...]   also scan DIR (default /usr/local /opt /srv /var/www /home)
                   for executables and libraries that embed their own expat,
                   such as vendored or statically linked copies.
  version          print the script version.

EXPAT_LIB_DIRS (space separated) replaces the default library search directories.
EXPAT_PY_DIRS (space separated) replaces the directories searched for Python interpreters.
Containers: with no argument the check also looks in running docker and podman containers
(SCAN_CONTAINERS=1, the default; 0 skips them). A read-only probe captures the daemon's version
output and its configuration (secrets are redacted inside the container before anything is
copied) into a private temporary directory, and this script then runs once per container, in
isolation, against that copy. Paths shown as .../docker_NAME/... are inside the container NAME.

The Security Patches software and this documentation are dedicated to the public domain under CC0 1.0 Universal. Other pages on privacysafe.app/docs are CC BY-SA 4.0 unless the page says otherwise.

The PrivacySafe Ecosystem

Shop at Ivy Cyber

Ivy Cyber offers PrivacySafe products and services in the USA and has partnerships with 3NSoft in Canada and Kuip Limited in the European Union. Enterprise services and consulting are available at ivycyber.com

PrivacySafe Foundation is a 501(c)(3) nonprofit public charity that supports the development of the PrivacySafe applications, along with the components they rely upon: 3NWeb protocols, filesystem, documentation, and reference implementations.

PrivacySafe Foundation

Donations to PrivacySafe Foundation support education, research, documentation, and public code. Purchases from Ivy Cyber support PrivacySafe products, services, hosting, and technical support. Together, we're building a better web.