CVE-2026-54058 Overview
CVE-2026-54058 is an out-of-bounds read vulnerability [CWE-125] in the Pillow Python imaging library affecting versions prior to 12.3.0. The flaw resides in the memory-mapped raw codec path used when loading uncompressed McIdas AREA images from a filename. Attacker-controlled header fields can specify a row stride smaller than the natural row width, causing subsequent pixel access operations to read past the mapped region. This exposes adjacent process memory to disclosure or triggers a process fault, depending on the memory layout at exploitation time.
Critical Impact
A crafted McIdas AREA file processed by Pillow can leak adjacent process memory or crash the interpreting service through pixel access APIs such as Image.tobytes(), getpixel, convert, or save.
Affected Products
- Python Pillow versions prior to 12.3.0
- Applications embedding vulnerable Pillow versions that accept McIdas AREA input
- Image-processing pipelines using Image.open() on untrusted files
Discovery Timeline
- 2026-07-14 - CVE-2026-54058 published to NVD
- 2026-07-15 - Last updated in NVD database
Technical Details for CVE-2026-54058
Vulnerability Analysis
The defect lives in src/map.c, which implements Pillow's memory-mapped raw image loader. When Pillow opens an uncompressed McIdas AREA image from a filename, it uses the mmap raw codec to expose file bytes directly as pixel data. The loader trusts header-derived values for image width (xsize), height (ysize), and row stride without validating that stride accommodates a full row of pixels at the current pixel size.
When stride is smaller than xsize * pixelsize, per-row pointer arithmetic still produces ysize row pointers that extend beyond the mapped region. Any subsequent pixel access, including Image.tobytes(), getpixel, convert, or save, dereferences memory outside the mapping. The result is either disclosure of adjacent process memory contained in the same address space or a segmentation fault.
Root Cause
Before the fix, src/map.c only reassigned stride when the caller passed a non-positive value. When a positive but undersized stride was supplied through the AREA header, it was accepted as-is. This missing lower-bound check on stride is the direct cause of the out-of-bounds read.
Attack Vector
Exploitation requires a target application to open a malicious McIdas AREA file through Pillow's file-name based loader. Web services that accept user-uploaded images, batch conversion pipelines, and thumbnailing workers are the primary exposure paths. No authentication is required when the processing endpoint is reachable over the network.
// Security patch in src/map.c (#9719) - enforce minimum stride
const ModeID mode = findModeID(mode_name);
- if (stride <= 0) {
- if (mode == IMAGING_MODE_L || mode == IMAGING_MODE_P) {
- stride = xsize;
- } else if (isModeI16(mode)) {
- stride = xsize * 2;
- } else {
- stride = xsize * 4;
- }
+ int pixelsize;
+ if (mode == IMAGING_MODE_L || mode == IMAGING_MODE_P) {
+ pixelsize = 1;
+ } else if (isModeI16(mode)) {
+ pixelsize = 2;
+ } else {
+ pixelsize = 4;
+ }
+ if (stride <= xsize * pixelsize) {
+ stride = xsize * pixelsize;
}
if (stride > 0 && ysize > PY_SSIZE_T_MAX / stride) {
Source: python-pillow/Pillow commit 6a8de89
The patch computes pixelsize from the image mode and forces stride to at least xsize * pixelsize, eliminating the undersized-stride condition regardless of header input.
Detection Methods for CVE-2026-54058
Indicators of Compromise
- Unexpected segmentation faults or crashes in Python processes calling PIL.Image.open() on uploaded content
- McIdas AREA files (.area, no extension) submitted to endpoints that do not typically receive scientific imagery
- Python worker processes emitting truncated or garbage pixel buffers from Image.tobytes() operations
Detection Strategies
- Inventory Python environments and identify installations of Pillow < 12.3.0 using pip list or SBOM tooling
- Instrument image-processing services to log Pillow version, input format, and header dimensions per request
- Alert on repeated Pillow-related exceptions such as OSError or SystemError originating from the raw codec path
Monitoring Recommendations
- Monitor upload endpoints for anomalous request volumes targeting rarely used image formats like McIdas AREA
- Correlate worker crashes with recent image uploads to identify probing activity
- Track outbound response sizes from image APIs for anomalies consistent with memory disclosure
How to Mitigate CVE-2026-54058
Immediate Actions Required
- Upgrade Pillow to version 12.3.0 or later across all Python environments
- Audit dependent applications and containers that ship Pillow as a transitive dependency
- Restrict accepted image formats at the application layer to those actually required by the workload
Patch Information
The fix is included in Pillow 12.3.0, published in GitHub Release 12.3.0. The code change is tracked in Pull Request #9719 and detailed in GHSA-62p4-gmf7-7g93. Upgrade with pip install --upgrade Pillow>=12.3.0 and rebuild any container images that pin an older version.
Workarounds
- Reject McIdas AREA files at the ingress layer if the format is not required
- Load images from in-memory buffers (BytesIO) instead of file paths to bypass the vulnerable mmap raw codec path
- Run image-processing workers in sandboxed, resource-limited containers to contain crashes and limit disclosure scope
# Upgrade Pillow across environments
pip install --upgrade 'Pillow>=12.3.0'
# Verify installed version
python -c "import PIL; print(PIL.__version__)"
# Optional: block AREA loader by removing the plugin at runtime
python -c "from PIL import Image, McIdasImagePlugin; Image.unregister_open('MCIDAS')"
Disclaimer: This content was generated using AI. While we strive for accuracy, please verify critical information with official sources.

