CVE-2026-112896 Overview
CVE-2026-112896 is an out-of-bounds read vulnerability [CWE-125] in Pillow, a widely used Python imaging library. The flaw affects Pillow's TIFF encoder in all versions prior to 13.0.0. The encoder can read beyond a ColorMap buffer when retained TIFF metadata declares a plane size inconsistent with BitsPerSample. An attacker crafts a small TIFF that opens normally but retains a malicious ColorMap. When an application re-encodes that image with libtiff, the mismatched metadata triggers the out-of-bounds read. The result is heap memory disclosure in the output file or a process crash.
Critical Impact
Attackers can disclose heap memory contents or crash services that re-encode untrusted TIFF images through Pillow.
Affected Products
- Pillow versions prior to 13.0.0
- Python applications using Pillow's TIFF encoder with libtiff
- Image processing pipelines that accept and re-encode user-supplied TIFF files
Discovery Timeline
- 2026-10-19 - CVE-2026-112896 published to NVD
- 2026-10-20 - Last updated in NVD database
- Fix released - Pillow 13.0.0 ships patch in commit d03dc3c
Technical Details for CVE-2026-112896
Vulnerability Analysis
The vulnerability lives in Pillow's TIFF save path, specifically where the encoder forwards retained metadata tags to libtiff. TIFF images may carry a ColorMap tag whose length must equal (1 << BitsPerSample) * 3 entries. Pillow failed to validate this invariant on save. An attacker opens a benign TIFF, then injects a ColorMap that does not match BitsPerSample. When the application calls save, the encoder in src/encode.c iterates the ColorMap buffer using the expected size derived from BitsPerSample, reading past the allocated allocation. The read reaches adjacent heap memory, which libtiff writes into the output stream or dereferences unsafely.
Root Cause
The root cause is missing input validation in src/PIL/TiffImagePlugin.py. The TIFF plugin accepted a ColorMap tag of arbitrary length without cross-checking BitsPerSample. Downstream C code assumed the tuple size matched 2^bits * 3.
Attack Vector
Exploitation requires that a target application open an attacker-supplied TIFF with Pillow and then re-encode it as TIFF via libtiff. Any network-exposed service that performs TIFF normalization, thumbnailing, or format conversion is in scope. No authentication or user interaction is required beyond submitting the image.
# Patch excerpt - src/PIL/TiffImagePlugin.py
# Source: https://github.com/python-pillow/Pillow/commit/d03dc3c587a9b0bdc9e4304d70d59a635a87b742
def _validate_tags(tags: dict[int, Any]) -> None:
if COLORMAP in tags:
bps = tags.get(BITSPERSAMPLE, 1)
if isinstance(bps, tuple):
bps = bps[0]
expected = (1 << bps) * 3
if len(tags[COLORMAP]) != expected:
msg = f"Requiring {expected} items for Colormap"
raise ValueError(msg)
The patch adds _validate_tags, which enforces the ColorMap length invariant before encoding. The companion change in src/encode.c initializes bits_per_sample defensively during tag processing.
Detection Methods for CVE-2026-112896
Indicators of Compromise
- Pillow processes that crash with segmentation faults while saving TIFF files
- Output TIFF files larger than input with unexpected ColorMap content
- Application logs showing libtiff errors referencing invalid ColorMap size
- Inbound TIFF uploads where header BitsPerSample disagrees with ColorMap tuple length
Detection Strategies
- Inventory Python environments for Pillow versions below 13.0.0 using pip list or SBOM tooling
- Instrument image-processing services to log TIFF tag metadata and flag ColorMap length mismatches with (1 << BitsPerSample) * 3
- Monitor for abnormal termination of worker processes handling user-submitted images
- Compare the entropy of saved TIFFs against the input image to detect heap memory leaked into the output
Monitoring Recommendations
- Alert on repeated crashes or restarts of image conversion workers
- Track outbound TIFF file sizes and byte distributions for anomalies that may indicate memory disclosure
- Enable core dump collection on image services to triage out-of-bounds reads
- Forward application logs to a central data lake for correlation across pipelines
How to Mitigate CVE-2026-112896
Immediate Actions Required
- Upgrade Pillow to version 13.0.0 or later across all Python environments
- Audit container images, serverless functions, and build artifacts for pinned Pillow versions
- Restrict TIFF uploads to trusted sources until the patch is deployed
- Review any cached user-supplied TIFFs that could be re-encoded by downstream jobs
Patch Information
The fix landed in commit d03dc3c587a9b0bdc9e4304d70d59a635a87b742 and is released in Pillow 13.0.0. The advisory GHSA-pchr-8j38-3x4p documents the issue. The patch adds the _validate_tags function to enforce ColorMap length consistency with BitsPerSample prior to encoding.
Workarounds
- Reject TIFF uploads where the ColorMap tag length does not equal (1 << BitsPerSample) * 3
- Convert incoming TIFFs to a safer intermediate format such as PNG before any re-encoding step
- Isolate image processing in sandboxed workers with strict memory limits to contain crashes
- Strip retained TIFF metadata tags before calling Image.save() when a direct upgrade is not possible
# Upgrade Pillow to the patched release
pip install --upgrade "Pillow>=13.0.0"
# Verify the 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.

