CVEReports
CVEReports

Automated vulnerability intelligence platform. Comprehensive reports for high-severity CVEs generated by AI.

Product

  • Home
  • Sitemap
  • RSS Feed

Company

  • About
  • Contact
  • Privacy Policy
  • Terms of Service

© 2026 CVEReports. All rights reserved.

Made with love by Amit Schendel & Alon Barad



CVE-2026-59205

CVE-2026-59205: Heap-Based Buffer Overflow in Pillow ImageCms Module

Amit Schendel
Amit Schendel
Senior Security Researcher

Jul 21, 2026·5 min read·39 visits

Executive Summary (TL;DR)

A heap-based buffer overflow exists in Pillow prior to 12.3.0's ImageCms module. Lacking verification of image modes allows writing multi-byte output data into under-allocated buffers, potentially enabling remote code execution.

CVE-2026-59205 is a high-severity heap-based out-of-bounds write vulnerability affecting Pillow prior to version 12.3.0. The flaw stems from a validation omission in the ImageCmsTransform class where source and destination image modes are not checked against the configurations defined during the creation of the transform. An attacker can exploit this discrepancy to trigger a heap buffer overflow or an out-of-bounds read by supplying an under-allocated target image buffer.

Vulnerability Overview

Pillow incorporates the LittleCMS (lcms2) library via its ImageCms module to perform high-fidelity color profile conversions. The ImageCmsTransform class handles these transformations by establishing custom input and output pixel modes, which correspond to specific internal memory layouts.

The vulnerability, designated as CVE-2026-59205, manifests when an application processes transformations via apply() or apply_in_place(). These APIs fail to validate that the pixel modes of user-supplied images correspond to the formats expected by the compiled transformation object.

Because the native C extension _imagingcms only performs coordinate-based boundary checks, it readily processes images with mismatched formats. This discrepancy allows multi-byte pixel structures to be written into buffers allocated for single-byte pixel layouts.

Root Cause Analysis

The root cause of this vulnerability lies in the lack of type and mode validation within the src/PIL/ImageCms.py Python layer and the corresponding _imagingcms.c native component. During transformation compilation, a handle is initialized with predefined source and destination formats, which dictate how many bytes are read and written per pixel.

When cmsDoTransform() is executed, the destination image's row buffer pointers are supplied directly to the LittleCMS engine. If the compiled transformation outputs 4-byte pixels (such as RGBA) but the target image is allocated with a 1-byte pixel mode (such as L), LittleCMS continues to write 4 bytes per pixel into the destination buffer.

This behavior causes a controlled out-of-bounds write of 3 bytes per pixel into adjacent heap chunks. Conversely, if the input image mode contains fewer bytes than expected by the transformation engine, an out-of-bounds heap read occurs, exposing adjacent memory contents.

Code Analysis and Remediation

The vulnerability was mitigated in Pillow version 12.3.0 by incorporating check assertions directly into the high-level Python wrappers inside src/PIL/ImageCms.py.

Prior to the patch, the apply method did not perform any validation of input or output modes:

def apply(self, im, imOut=None):
    if imOut is None:
        imOut = Image.new(self.output_mode, im.size, None)
    self.transform.apply(im.getim(), imOut.getim())
    imOut.info["icc_profile"] = self.output_profile.tobytes()
    return imOut

The corrected implementation establishes strict equality validations prior to invoking the C extension:

def apply(self, im: Image.Image, imOut: Image.Image | None = None) -> Image.Image:
    if im.mode != self.input_mode:
        msg = "mode mismatch"
        raise ValueError(msg)
    if imOut is not None:
        if imOut.mode != self.output_mode:
            msg = "mode mismatch"
            raise ValueError(msg)
    else:
        imOut = Image.new(self.output_mode, im.size, None)
    self.transform.apply(im.getim(), imOut.getim())
    imOut.info["icc_profile"] = self.output_profile.tobytes()
    return imOut

These checks ensure that the physical structures allocated for the images match the spatial logic expected by the native code.

Defense-in-Depth Analysis & Bypass Risks

Although the current validation checks successfully address the public API vector, implementing defenses purely at the Python layer introduces a potential gap in defensive controls. If an attacker is capable of executing limited python code, they can directly import and call the binary extension module _imagingcms.

Because the underlying C-code wrappers do not check the mode attribute of the ImagingCore structures, direct calls to the underlying transform engine still result in a heap out-of-bounds write. Furthermore, if custom image classes can spoof the .mode property while returning an under-allocated buffer on .getim(), the Python-level checks can be circumvented.

To ensure complete isolation, future iterations of Pillow should incorporate these size-assertion validations inside the native C extension _imagingcms.c before passing pointers to the lcms2 library.

Exploitation and Attack Methodology

To exploit this vulnerability, an attacker must submit an image that forces the application to perform a color space transformation where the source or target image buffers are mismatched. An application that automatically converts user uploads to a standardized color profile is highly vulnerable to this scenario.

Because the bytes written to the adjacent heap space represent the translated pixels of the source image, an attacker can construct custom pixel matrices to control the corrupted data. By crafting the input pixel coordinates and color values, the attacker can precisely overwrite adjacent metadata blocks, targeting function pointers or control structures on the heap to execute arbitrary code.

Impact Assessment

The vulnerability is assigned CVSSv3.1 score 7.5 (High) due to the potential for total loss of process availability. In environments where Pillow processes image uploads, exploitation immediately leads to process termination or denial of service.

In scenarios where memory protections such as ASLR are bypassed or where control over heap layouts is mature, heap corruption can be weaponized to compromise system integrity. This vulnerability is of critical concern for multi-tenant image hosting services and document processing pipelines.

Official Patches

python-pillowGitHub Security Advisory
python-pillowPull Request #9715: Fix ImageCms mode mismatch

Fix Analysis (1)

Technical Appendix

CVSS Score
7.5/ 10
CVSS:3.1/AV:N/AC:L/PR:N/UI:N/S:U/C:N/I:N/A:H
EPSS Probability
0.39%
Top 69% most exploited

Affected Systems

Pillow (Python Imaging Library)

Affected Versions Detail

Product
Affected Versions
Fixed Version
Pillow
python-pillow
< 12.3.012.3.0
AttributeDetail
CWE IDCWE-787
Attack VectorNetwork (AV:N)
CVSS v3.17.5 (High)
ImpactAvailability (High)
Exploit StatusProof of Concept available in tests
KEV StatusNot listed

MITRE ATT&CK Mapping

T1203Exploitation for Client Execution
Execution
T1068Exploitation for Privilege Escalation
Privilege Escalation
CWE-787
Out-of-bounds Write

The software writes data past the end, or before the beginning, of the intended buffer, resulting in corruption of data, a crash, or code execution.

Known Exploits & Detection

GitHub (Pillow Test Suite)Functional unit tests demonstrating parameters matching and raising ValueError on mode mismatch.

Vulnerability Timeline

Vulnerability reported privately to Pillow maintainers
2026-04-14
Validation patch developed and committed to main repository
2026-06-23
Security advisory published and CVE-2026-59205 registered
2026-07-14
Pillow 12.3.0 released with complete validation fix
2026-07-14

References & Sources

  • [1]GitHub Security Advisory GHSA-9hw9-ch79-4vh6
  • [2]Pillow Patch Commit
  • [3]Pillow Pull Request #9715
  • [4]Pillow 12.3.0 Release Notes
  • [5]NVD CVE-2026-59205 Entry
  • [6]CVE.org Record

Attack Flow Diagram

Press enter or space to select a node. You can then use the arrow keys to move the node around. Press delete to remove it and escape to cancel.
Press enter or space to select an edge. You can then press delete to remove it or escape to cancel.

More Reports

•39 minutes ago•CVE-2026-53653
8.7

CVE-2026-53653: Unauthenticated Denial of Service via Unbounded Image Derivative Dimensions in Grav CMS

Grav CMS prior to version 1.7.53 and 2.0.0-rc.8 is vulnerable to an unauthenticated remote denial of service (DoS) vulnerability. By supplying crafted query parameters with extremely large dimensions to image assets, remote unauthenticated attackers can force the server to allocate massive amounts of system memory, leading to kernel Out-Of-Memory (OOM) termination of web worker processes.

Amit Schendel
Amit Schendel
2 views•7 min read
•about 2 hours ago•CVE-2026-53657
8.2

CVE-2026-53657: Privilege Escalation via Overly Permissive Unix Domain Socket in Lima Guest Agent

CVE-2026-53657 is a local privilege escalation vulnerability in Lima (lima-vm/lima) affecting versions prior to 2.1.3 when configured with the QEMU driver. The guest agent daemon, running as root, creates its communication socket `/run/lima-guestagent.sock` with world-writable permissions (0777). This allows unprivileged local users to command the agent to establish arbitrary tunnels, including to privileged local UNIX sockets (like D-Bus). Because the target daemon authenticates the incoming connection using the credentials of the root-owned guest agent (via SO_PEERCRED), unprivileged users can perform root operations, resulting in complete guest VM compromise.

Amit Schendel
Amit Schendel
2 views•9 min read
•about 3 hours ago•CVE-2026-10740
5.3

CVE-2026-10740: Denial of Service in s2n-quic CryptoStream Reassembly

An unauthenticated Denial of Service vulnerability exists in the s2n-quic library's CryptoStream reassembler due to a lack of buffer limits on out-of-order cryptographic frames. An attacker can transmit a crafted CRYPTO frame with an extremely high offset and nominal payload, forcing the receiver to execute unbounded memory allocations and causing service crashes.

Amit Schendel
Amit Schendel
3 views•7 min read
•about 4 hours ago•CVE-2026-55153
7.1

CVE-2026-55153: JNDI Injection and Deserialization Gadget Abuse in mchange-commons-java

A JNDI Injection and Deserialization Gadget vulnerability exists in mchange-commons-java prior to version 0.6.0. The com.mchange.v2.naming.JavaBeanObjectFactory component permits arbitrary class instantiation and setter invocation, allowing attackers to perform Server-Side Request Forgery (SSRF) and remote class loading.

Alon Barad
Alon Barad
6 views•5 min read
•about 5 hours ago•GHSA-8RW6-P7M8-63JP
6.5

GHSA-8RW6-P7M8-63JP: Array Element-Level SELECT Permissions Leak in SurrealDB

SurrealDB versions supporting element-level SELECT permissions on arrays are vulnerable to a logical authorization bypass. Due to an index-shifting error during array filtration, restricted elements can skip permission checks and leak to unauthorized record users.

Alon Barad
Alon Barad
5 views•6 min read
•1 day ago•CVE-2026-12243
7.5

CVE-2026-12243: Incomplete Path Traversal Validation and Percent-Encoding Bypass in NLTK

CVE-2026-12243 is a path traversal vulnerability in the Natural Language Toolkit (NLTK) version 3.9.4. The flaw exists because the input validation routine fails to account for percent-encoded directory traversal sequences like '..%2f' before passing them to urllib.request.url2pathname(), which decodes them into active traversal sequences.

Amit Schendel
Amit Schendel
5 views•8 min read