Operating system, libraries and runtimes
Pillow 13.0.0: CVE-2026-96639 and CVE-2026-112900 check
Pillow 13.0.0 security release check
Pillow is one of the most widely installed imaging libraries for Python: web uploads, thumbnails, document pipelines, machine-learning data loaders. Pillow 13.0.0, announced on oss-security on 21 October 2026, fixes a long list of memory-safety and parsing bugs. This tool covers two of them. The release notes list many more, including JPEG decoder overflows, TIFF encoder overflows and PDF parsing problems, and all of them are fixed by the same upgrade.
| Item | CVE-2026-96639 | CVE-2026-112900 |
|---|---|---|
| What | Stale native image storage reused after a mode transition. A multi-frame file can keep an allocation made for a narrow frame mode while a later frame of the same size switches to wider RGB or CMYK data, so pixels are written past the allocation | EpsImagePlugin passes the caller-supplied filename after -f to Ghostscript without making it an absolute path. A name that starts with a hyphen is read as a Ghostscript option, and a name that starts with @ names an argument file |
| Affected | 11.0.0 up to 13.0.0 | 2.6.0 up to 13.0.0 |
| Fixed | 13.0.0 | 13.0.0 |
| Files | Crafted PSD, MPO, DCX or MIC files | EPS input, or any call that hands Pillow an attacker-chosen filename |
| Impact | Native out-of-bounds writes and crashes. The MPO path can also read out of bounds and, in demonstrated runtime-specific profiles, run commands | Option injection into Ghostscript. Command execution needs the attacker to control the filename and the text file it names; the reported chain works with the default -dSAFER |
| Severity | 9.8 Critical | Listed as 9.2 Critical |
Quick start
-
Download the script. The repository is mirrored on GitHub and Codeberg; pick a base URL.
# BASE from GitHub: https://raw.githubusercontent.com/PrivacySafe/security-patches/refs/heads/main # BASE from Codeberg: https://codeberg.org/PrivacySafe/security-patches/raw/branch/main # curl -fLO "$BASE/pillow/pillow-oct2026-check.sh" curl -fLO https://raw.githubusercontent.com/PrivacySafe/security-patches/refs/heads/main/pillow/pillow-oct2026-check.sh -
Read it before running it, then make it executable.
less pillow-oct2026-check.sh chmod +x pillow-oct2026-check.sh -
Check this host. By default it searches
/usr/lib /usr/local/lib /opt /srv /var/www /var/lib /home /root; pass directories to narrow it../pillow-oct2026-check.sh check ./pillow-oct2026-check.sh check /srv/myapp/.venv
Commands
| Command | What it does |
|---|---|
check [DIR ...] (default) |
Finds installed copies from Pillow-*.dist-info and *.egg-info metadata, and declared pins in requirements*.txt, poetry.lock, uv.lock, pdm.lock and Pipfile.lock. Compares each version with both CVEs and reports whether Ghostscript (gs) is on PATH |
version |
Prints the script version |
Exit codes: 0 nothing affected, 1 an affected version was found, 2 bad arguments.
How to read the result
- Both bugs apply: the version is in both ranges. If
gsis installed the script prints a critical line for CVE-2026-112900 as well. - Affected by CVE-2026-112900 but no
gs: the script prints a warning and says the EPS path is inert on this host. The script still exits1, because the same Pillow version is affected by the other fixes in 13.0.0. - Lock file pins describe what would be installed, not what is running. A pin points to what to fix. Check the running server for exposure.
pillow-heifand other packages that merely start with "pillow" are not matched.- Distribution packages. For copies owned by a
dpkgorrpmpackage the script reads the package changelog and reports a mention of either CVE, because distributions backport fixes without changing the version string.
Fixing it
pip install --upgrade 'Pillow>=13.0.0'
Check that your Python version is supported by Pillow 13.x before you pin it. Rebuild container images, and restart long-running workers, because a running process keeps the old library loaded.
If you cannot upgrade yet:
- CVE-2026-96639: open untrusted files with an allowlist of formats, for example
Image.open(f, formats=["JPEG", "PNG", "GIF", "WEBP"]), which keeps PSD, MPO, DCX and MIC out. Pillow's own security guidance recommends this approach. - CVE-2026-112900: reject EPS input, or reject any filename that starts with
-or@before it reaches Pillow, or remove Ghostscript from hosts that do not need it. Pillow's guidance also recommends blocking EPS at the application boundary. - For both, run image processing in a sandbox without network access and without sensitive mounts.
Sources
- oss-security: Pillow 13.0.0 fixes long list of vulnerabilities
- Pillow 13.0.0 release notes
- Pillow security handbook
Before you run it
- The fix. Update Pillow to 13.0.0, which fixes both flaws.
- CVE-2026-112900 needs Ghostscript. The EPS bug passes a filename to the
gsbinary, so the script reports whether Ghostscript is installed. Command execution needs the attacker to control the filename and the referenced text file. - It reads installed metadata and lock files. It finds Pillow in Python environments (
dist-infoandegg-info) and in lock files and compares versions. - There is no hunt. No indicators of exploitation have been published.
- It also checks running docker and podman containers, unless you name a directory or set
SCAN_CONTAINERS=0. In each running container, a read-only probe finds the installed copies by theirdist-infoandegg-infofolders, plus the lock and requirements files that mention the package. It copies only those names and files into a private temporary folder, and the normal check judges that folder. Whether Ghostscript is installed decides if the EPS flaw (CVE-2026-112900) is reachable, so a copy found in a container is judged by that container'sgs, not the host's. A staged symlink is never kept and the copies are removed on exit. A path shown as.../docker_NAME/PATHis the PATH inside the container NAME. It is skipped when you name directories yourself.
Red Hat advisories
Red Hat's advisory list (security advisories released 2026-04-01 to 2026-11-03) names the CVEs below. A Red Hat build is judged by its RPM release, not by the upstream version number, because Red Hat backports fixes: the advisory names the release that fixes it. A CVE with no advisory in the list has none for that period, which is not the same as not affected. The current state is on Red Hat's CVE database.
| Advisory | Released | Severity | Package and stream | CVEs on this page |
|---|---|---|---|---|
| RHSA-2026:93077 | 2026-10-30 | Critical | python-pillow-5.1.1-36.el8_10 (RHEL 8.10) |
CVE-2026-112900 |
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.