CVE-2026-59198 Overview
CVE-2026-59198 is an out-of-bounds read vulnerability in Pillow, the Python imaging library. The flaw resides in the TGA run-length encoding (RLE) encoder when saving mode 1 (1-bit) images. The encoder reads past its packed row buffer, allowing adjacent process heap bytes to be copied into the generated TGA file. Affected versions span from 5.2.0 up to but not including 12.3.0. The issue is tracked as [CWE-125] Out-of-Bounds Read and resolved in Pillow 12.3.0.
Critical Impact
Sensitive process memory can leak into attacker-accessible TGA output files, exposing secrets, tokens, or key material handled by the same Python process.
Affected Products
- Python Pillow versions 5.2.0 through 12.2.x
- Applications embedding Pillow for TGA image conversion
- Automated image processing pipelines that accept mode 1 inputs
Discovery Timeline
- 2026-07-14 - CVE-2026-59198 published to the National Vulnerability Database (NVD)
- 2026-07-14 - Last updated in NVD database
- Fix released - Pillow 12.3.0 published on GitHub with commit eada3cbd7fb9963ee90673fb7b5270124a0d5f4b
Technical Details for CVE-2026-59198
Vulnerability Analysis
The defect lives in src/PIL/TgaImagePlugin.py, specifically in the path that serializes mode 1 (1-bit black-and-white) images using TGA run-length compression. When Pillow packs a mode 1 row, each byte encodes eight pixels. The RLE encoder, however, iterates over pixel counts rather than the packed byte length. It therefore reads bytes beyond the end of the packed row buffer.
Those out-of-bounds bytes come from whatever process heap memory sits adjacent to the packed row. The bytes are written into the resulting .tga file, where an attacker who receives or downloads the file can inspect them. The disclosed information may include fragments of other images, credentials, environment data, or cryptographic material held by the same process. The classification aligns with [CWE-125] Out-of-Bounds Read.
Root Cause
The root cause is a mismatch between the pixel count driving the encoder loop and the actual byte length of the packed 1-bit row. Because 8 pixels compress into a single byte for mode 1, the encoder overshoots the buffer by up to a factor of 8. No bounds check gated the read against the packed row length before the fix.
Attack Vector
Exploitation requires an attacker to influence a Pillow-based service into saving a mode 1 image as TGA with tga_rle compression, then to retrieve the generated file. Any web service, converter, or thumbnail pipeline that accepts user-supplied images and offers TGA output can leak heap contents into files attackers subsequently download.
compression = im.encoderinfo.get("compression", im.info.get("compression"))
rle = compression == "tga_rle"
if rle:
+ if im.mode == "1":
+ msg = f"cannot write mode {im.mode} as TGA with run-length encoding"
+ raise OSError(msg)
+
imagetype += 8
id_section = im.encoderinfo.get("id_section", im.info.get("id_section", ""))
# Source: https://github.com/python-pillow/Pillow/commit/eada3cbd7fb9963ee90673fb7b5270124a0d5f4b
The patch refuses to encode mode 1 images with TGA RLE by raising OSError, closing the code path that triggered the overread.
Detection Methods for CVE-2026-59198
Indicators of Compromise
- TGA files generated by Pillow-based services containing high-entropy trailing bytes not matching expected pixel data
- Application logs showing Image.save() calls with format="TGA" and compression="tga_rle" on mode 1 inputs
- Outbound transfers of .tga files whose byte length exceeds the expected packed size for the declared image dimensions
Detection Strategies
- Inventory Python environments and identify installed Pillow versions using pip show pillow or software composition analysis tooling
- Flag any Pillow release with version <12.3.0 as vulnerable
- Add runtime hooks or code review rules that alert when TGA output combines mode 1 conversion and tga_rle compression
Monitoring Recommendations
- Track file uploads and downloads on services that expose Pillow-based image conversion, correlating requests with output file size anomalies
- Alert on stack traces referencing TgaImagePlugin in application logs
- Monitor dependency manifests (requirements.txt, pyproject.toml, Pipfile.lock) for Pillow pinned below 12.3.0
How to Mitigate CVE-2026-59198
Immediate Actions Required
- Upgrade Pillow to version 12.3.0 or later across all production, staging, and developer environments
- Rebuild and redeploy container images that bundle Pillow so runtime instances receive the fix
- Audit stored TGA artifacts generated by prior versions and treat their contents as potentially sensitive
Patch Information
The fix ships in Pillow 12.3.0 via commit eada3cbd7fb9963ee90673fb7b5270124a0d5f4b, merged through Pillow pull request #9709. Additional context is available in the GitHub Security Advisory GHSA-fj7v-r99m-22gq and the Pillow 12.3.0 release notes.
Workarounds
- Disable TGA RLE output by removing compression="tga_rle" from Image.save() calls
- Convert mode 1 images to mode L or RGB before saving as TGA, avoiding the vulnerable code path
- Restrict user-supplied image formats to disallow forcing TGA output where feasible
# Upgrade Pillow across environments
pip install --upgrade "Pillow>=12.3.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.

