Article
eMudhra CA Key Compromise: What Python, uv and Container Teams Must Update Now
Eight eMudhra CA keys were weak enough to recover. See what is true about the pip claim and the exact update and check list…
Quick links
Press Enter to search, Esc to close
Vulnerability
A heap buffer overflow in the FlashPix (FPX) reader of Pillow, the Python imaging library.
In short
CVE-2026-112398 is a heap buffer overflow in the FlashPix (FPX) reader of Pillow, the Python imaging library. A crafted file opened with Image.open() can write past a memory buffer, and the reporter's proof of concept turns that into command execution. It needs the optional olefile package. The Pillow maintainers rate it critical (GitHub: CVSS 4.0 9.2), and Pillow 13.0.0 fixes it.
The flaw is in how Pillow, the Python imaging library, reads FlashPix (FPX) files. FPX files are OLE2 compound documents. Pillow reads them only when the optional olefile package is installed. Pillow's documentation says you must install olefile to enable FPX support.
An FPX file can hold a JPEG-compressed picture. For that case Pillow takes the colour setting from the file and sizes a one-row buffer from it. In the advisory's example the setting gives a mode with two bytes per pixel (LA). The JPEG data inside the file can say it has four components.
The JPEG library then writes four bytes per pixel into a buffer made for two, and the extra bytes land in the heap next to it. The attacker controls how far it overflows, because that follows the image width, and what the bytes are, because they are the decoded pixels.
The reporter, Alex Bouffard, uses this in the proof of concept to overwrite a Python object next to the buffer. The interpreter then calls the C function system with a command the attacker chose.
Pillow picks the format from the file content, not from the name. The OLE2 signature at the start of the file is enough, whatever the extension. So a service that makes thumbnails of uploads with Image.open() reaches this code with no click from a user, if olefile is installed.
Conditions apply. olefile must be present, and an outsider must be able to get a file to Image.open(). GitHub's score uses attack complexity high.
The reporter's demonstration ran on Pillow 12.2.0 in a Docker image with address space layout randomization (ASLR) switched off, on a Python binary that is not position independent. In that demonstration the process also aborted on a corrupted heap after the command had run. NVD says the flaw may allow arbitrary code execution. On a normal server an attack needs more work than in the demonstration, but it is not ruled out.
Our checks on 24 October 2026 showed the following. GitHub: the reporter's proof of concept, a Dockerfile and a payload builder script, is public inside the advisory itself. X: 5 posts from 22 and 23 October matched our searches. They repeat the advisory and give upgrade advice.
Dark web monitoring through Blackhole: 1 post carries the CVE id. It is on Telegram, from 20 October, in a CVE digest channel that lists it with three other critical Pillow flaws. These are aggregate counts. We did not run the proof of concept, and we link only the advisory that contains it.
CISA had not listed the CVE in its Known Exploited Vulnerabilities catalog in the file released on 23 October. Treat it as a flaw to fix now for any service that opens untrusted files, and check olefile first, because that tells you quickly whether you are exposed.
The same release fixes a related JPEG decoder flaw. Pillow's release notes list this advisory and GHSA-8g5g-8vmr-9782 (CVE-2026-112403) as one entry under critical. The entry is called "JPEG decoder buffer overflow from scanlines wider than tile extents". Pillow is often pulled in as a dependency of other packages, so it can sit in your software bill of materials without anyone having chosen it.
The Pillow advisory lists Pillow up to and including 12.3.0 as affected. The NVD entry says prior to 13.0.0. Pillow 13.0.0, released on 16 October 2026, is the only patched version the advisory lists.
A service is exposed only if three things hold. Pillow 12.3.0 or older and olefile are both installed in the same environment. The app also passes files an outsider can influence to Image.open(), with no formats list that leaves FPX out.
The fix is a check in Pillow's JPEG decoder (change 10131, dated 6 October). Before the decoder hands a line to the buffer, it compares the line width and the bytes per line that libjpeg will produce with the buffer size. It rejects the stream if they do not fit.
Pillow 13.0.0 needs Python 3.11 or newer. A service still on Python 3.10 cannot install it, so remove olefile or set a formats list (see below) until it moves to a newer Python. Our page on the Pillow EPS Ghostscript flaw CVE-2026-112900 lists the other Pillow flaws that GitHub rates critical and that 13.0.0 fixes, so one upgrade closes all of them.
A Pillow change dated this day makes the JPEG decoder reject streams whose lines are wider than the buffer or have more components. The CVE record and the GitHub advisory link to this change.
Pillow 13.0.0 is released on GitHub with the fix.
The Pillow maintainers publish advisory GHSA-5x8w-8jj5-q52h on GitHub and rate it critical.
The CVE record is published in the National Vulnerability Database, with GitHub as the source.
GitHub's advisory database publishes the related JPEG decoder advisory GHSA-8g5g-8vmr-9782 (CVE-2026-112403), also critical.
GitHub's advisory database adds this entry, critical, with a CVSS 4.0 score of 9.2.
Run pip show olefile in each Python environment and container image that has Pillow. If olefile is not there, Pillow does not read FPX files, so this flaw is not reachable through it.
Run pip show pillow, or search your lock files (requirements.txt, poetry.lock, Pipfile.lock, uv.lock) and container images for pillow. Version 12.3.0 and older is affected. Look in the dependencies of other packages too.
Run pip install --upgrade pillow in a Python version that Pillow 13 supports, then rebuild images and lock files. Pillow 13 needs Python 3.11 or newer.
Remove olefile if you do not need FPX or MIC files. Or pass a formats list to Image.open(), for example formats=["PNG", "JPEG"]. Pillow documents that list as the set of formats it tries. This closes the FPX path only, not the related JPEG flaw CVE-2026-112403.
The advisory says the code runs as the process that handles the image. Run thumbnailing and conversion in a low-privilege container that holds no secrets and has no route to internal systems.
List every place an upload, a mail attachment or a downloaded file is passed to Image.open(), including libraries and plugins of your own stack that use Pillow for this.
CISA had not listed it in the Known Exploited Vulnerabilities catalog in the file released on 23 October 2026. A proof of concept is public inside the advisory, so attacks are possible.
Yes. The advisory says the flaw is reachable when the optional olefile package is installed, and Pillow's documentation says olefile is needed to enable FPX support.
No. The advisory says Pillow recognises the file by its OLE2 signature, not by its extension, so a renamed file is still read as FPX.
Pillow 13.0.0, the only patched version in the advisory. It needs Python 3.11 or newer.
No, they are separate CVE ids. Pillow's release notes list the two advisories in one entry, and the CVE-2026-112403 advisory describes the same kind of mistake in the JPEG decoder, lines wider than the buffer.
Yes. Remove olefile, or pass Image.open() a formats list that leaves out FPX (see the steps above). This closes the FPX path only, not the related JPEG flaw CVE-2026-112403.
Take control of your digital security with an exclusive demo of our AI-driven threat intelligence platform.