Skip to main content
Vulnerability Database/CVE-2026-112393

CVE-2026-112393: Pillow Buffer Overflow Vulnerability

CVE-2026-112393 is a heap buffer overflow vulnerability in Pillow Python imaging library affecting versions 2.0.0 to 13.0.0. Attackers can exploit this flaw to crash processes or execute code. This article covers technical details, affected versions, impact assessment, and mitigation strategies.

Published:

CVE-2026-112393 Overview

CVE-2026-112393 is a heap buffer overflow and stale-heap disclosure vulnerability in Pillow, the widely used Python imaging library. The flaw resides in the _tiffWriteProc callback used when saving compressed TIFF data through libtiff to targets without a usable fileno(), such as BytesIO. Attackers can trigger the overflow using crafted out-of-line TIFF tags or retained ICC profiles that get copied beyond the allocated buffer after libtiff seeks forward. The flaw affects Pillow from version 2.0.0 up to 13.0.0 and is categorized as a heap-based buffer overflow [CWE-122].

Critical Impact

Exploitation can crash the Python process and may allow arbitrary code execution. Additionally, stale heap memory contents can leak to attackers through unwritten alignment gaps in compressed TIFF output larger than 64 KiB.

Affected Products

  • Pillow versions 2.0.0 through 12.x (all releases prior to 13.0.0)
  • Python applications saving compressed TIFF data to BytesIO or other targets lacking a real file descriptor
  • Image processing pipelines that pass user-supplied TIFF tags or ICC profiles through Pillow's libtiff integration

Discovery Timeline

  • 2026-10-19 - CVE-2026-112393 published to NVD
  • 2026-10-20 - Last updated in NVD database

Technical Details for CVE-2026-112393

Vulnerability Analysis

The vulnerability exists in src/libImaging/TiffDecode.c within the _tiffWriteProc callback. When Pillow saves compressed TIFF data to a target without a real file descriptor, libtiff invokes this callback to write encoded bytes into a managed buffer. The callback must grow this buffer dynamically as libtiff writes directory entries and image data.

The root issue is that the reallocation loop sizes the new buffer using the prior state->size instead of the current write location state->loc. Because libtiff can seek past the current end of the buffer (for example when writing the TIFF directory), the computed required size can be substantially smaller than needed. The subsequent write then copies attacker-influenced bytes past the end of the heap allocation.

Root Cause

The flaw is a boundary calculation error in the heap growth logic of the TIFF write callback. The allocation grows based on size + state->size, but the correct target must be size + state->loc. When an attacker-controlled out-of-line TIFF tag or an embedded ICC profile is copied after libtiff has seeked forward, the write exceeds the allocation. A secondary defect leaves alignment gaps in compressed TIFF output larger than 64 KiB uninitialized, exposing stale heap bytes to anyone who can read the resulting TIFF.

Attack Vector

An attacker supplies crafted TIFF metadata (out-of-line tags or an ICC profile) to a server-side pipeline that re-encodes images to compressed TIFF using Pillow and writes to an in-memory buffer such as BytesIO. File paths and targets backed by real file descriptors are not affected because they use a different write path. The overflow can corrupt heap metadata, enabling process crashes or, in some configurations, arbitrary code execution. The disclosure variant requires no crafted tag and leaks heap bytes passively through alignment padding.

c
// Patch from src/libImaging/TiffDecode.c - fixes heap buffer overflow
// Source: https://github.com/python-pillow/Pillow/commit/11582e5ffbdceb973d5ee593f3105af5a9852b40
     TIFFSTATE *state = (TIFFSTATE *)hdata;
     tsize_t to_write;

+    // libtiff may have seeked past the end of the buffer, e.g. when writing the
+    // directory, so the required size is based on the current location.
     to_write = MIN(size, state->size - (tsize_t)state->loc);
     if (state->flrealloc && size > to_write) {
         tdata_t new_data;
         tsize_t newsize = state->size;
-        while (newsize < (size + state->size)) {
+        while (newsize < (size + (tsize_t)state->loc)) {
             if (newsize > INT_MAX - 64 * 1024) {
                 return 0;
             }

The patch recalculates the needed buffer size using state->loc (the current write offset) rather than state->size, ensuring the reallocation accommodates libtiff's forward seeks.

Detection Methods for CVE-2026-112393

Indicators of Compromise

  • Unexpected crashes or segmentation faults in Python worker processes that handle image conversion to TIFF
  • TIFF output artifacts containing non-zero bytes within alignment padding regions, indicating stale heap disclosure
  • Server logs showing abnormal termination of Pillow-based image processing jobs when input contains large or unusual ICC profiles

Detection Strategies

  • Inventory Python environments and identify all installations of Pillow with versions less than 13.0.0 using pip list or software bill of materials tooling
  • Audit application code for calls to Image.save() with format="TIFF" and compression options where the destination is BytesIO or any non-file target
  • Review image processing APIs that accept user-supplied TIFF tags or ICC profiles and forward them to Pillow

Monitoring Recommendations

  • Monitor process crash telemetry on image-processing workers for signatures consistent with heap corruption in libtiff or _imaging modules
  • Enable AddressSanitizer or similar runtime memory diagnostics in staging environments to surface overflows during fuzz testing
  • Alert on sudden increases in 5xx responses from endpoints that convert user images to TIFF format

How to Mitigate CVE-2026-112393

Immediate Actions Required

  • Upgrade Pillow to version 13.0.0 or later across all affected Python environments, including containers and serverless runtimes
  • Audit dependency manifests (requirements.txt, pyproject.toml, Pipfile.lock) to pin Pillow>=13.0.0 and rebuild images
  • Reject or sanitize untrusted TIFF inputs at ingress until patched builds are deployed

Patch Information

The issue is fixed in Pillow 13.0.0. The remediation commit 11582e5ffbdceb973d5ee593f3105af5a9852b40 corrects the buffer growth calculation in _tiffWriteProc and addresses the stale heap disclosure. See the GitHub Security Advisory GHSA-332p-7hrc-92wf and the Pillow 13.0.0 release notes for complete details.

Workarounds

  • Save compressed TIFF output to a real file path or file descriptor rather than BytesIO, since paths and real file descriptors are not affected
  • Disable TIFF compression or avoid re-encoding user-supplied images to TIFF in server pipelines until the upgrade is complete
  • Strip ICC profiles and out-of-line TIFF tags from untrusted inputs before passing them to Pillow
bash
# Upgrade Pillow to the patched release
python -m pip install --upgrade "Pillow>=13.0.0"

# Verify installed version
python -c "import PIL; print(PIL.__version__)"

Disclaimer: This content was generated using AI. While we strive for accuracy, please verify critical information with official sources.

Experience the Most Advanced Cybersecurity Platform

See how the world’s most intelligent, autonomous cybersecurity platform can protect your organization today and into the future.