Advisory Database
  • Advisories
  • Dependency Scanning
  1. pypi
  2. ›
  3. Pillow
  4. ›
  5. CVE-2026-128067

CVE-2026-128067: Pillow: Heap buffer overflow saving TIFF with libtiff when tags override image size

November 12, 2026

============================================================================
ANT-2026-CS7N494P  [high]  CWE-787  memory-safety
Heap buffer overflow saving TIFF with libtiff when tags override image size
Location: src/libImaging/TiffDecode.c:1035  in ImagingLibTiffEncode()
Commit:   a707c6b21c313880d0771e54965d142dd42358b6
============================================================================

When Pillow saves an image as a compressed TIFF, size information taken from the image’s metadata can make the encoder read past the end of a heap buffer. Someone who uploads an image can use this to get the server process’s memory, including pointers, copied into the saved file, or to crash the process. When the metadata also enables TIFF “Predictor=2” compression, the encoder writes past the buffer instead, corrupting the heap and aborting the process. This affects applications that write TIFF through libtiff (any compression= other than raw) and either carry the source metadata across with exif=im.getexif() / tiffinfo=, or simply re-save a crafted palette TIFF with Image.open(f).save(out, "TIFF"), which inherits its compression and predictor from the upload.

In TiffImagePlugin._save’s libtiff branch, only BitsPerSample is pinned to the real image when the tag list for the encoder is built (src/PIL/TiffImagePlugin.py:1955). ImageWidth, ImageLength and PlanarConfiguration are set from im.size but are then overwritten by the exif=/tiffinfo= merge loop at :1768-1772. SamplesPerPixel is never set for single-band modes, so a value from the caller’s tags or from the source TIFF’s own IFD reaches TIFFSetField. ImagingLibTiffEncode then passes a row buffer sized from the actual image (src/encode.c:291) to TIFFWriteScanline (src/libImaging/TiffDecode.c:1035) with no check against TIFFScanlineSize(), and libtiff consumes a full scanline of the tag-described width from it.

The attached reproducer demonstrates the read case. A 64x4 greyscale JPEG whose EXIF says SamplesPerPixel=3, Photometric=RGB is converted into a valid RGB TIFF in which 128 bytes of each row are live heap, including pointers that change from run to run. The same JPEG with EXIF ImageWidth=2**27 kills the process with SIGSEGV. For the write case, the values written are byte-wise differences of existing heap contents rather than attacker-chosen data, and nothing beyond the observed glibc abort is shown. The tiffinfo= route dates back to Pillow 2.3.0 (dbf47837ce99), and the exif= route to 8.4.0 (c0f619384cbc).

References

  • github.com/advisories/GHSA-xcvg-w56q-r89m
  • github.com/python-pillow/Pillow/commit/53318b50e8e9e85a57d033d4d879e1398d97aeb1
  • github.com/python-pillow/Pillow/commit/ec5f1cbcf67275641abaad5c065ffb64a0a804a9
  • github.com/python-pillow/Pillow/releases/tag/13.0.0
  • github.com/python-pillow/Pillow/security/advisories/GHSA-xcvg-w56q-r89m
  • nvd.nist.gov/vuln/detail/CVE-2026-128067

Code Behaviors & Features

Detect and mitigate CVE-2026-128067 with GitLab Dependency Scanning

Secure your software supply chain by verifying that all open source dependencies used in your projects contain no disclosed vulnerabilities. Dependency Scanning using SBOM also detects vulnerabilities from proprietary advisories that this site does not include. Learn more about Dependency Scanning using SBOM →

Affected versions

All versions before 13.0.0

Fixed versions

  • 13.0.0

Solution

Upgrade to version 13.0.0 or above.

Impact 9.4 CRITICAL

CVSS:3.1/AV:N/AC:L/PR:N/UI:N/S:U/C:H/I:L/A:H

Learn more about CVSS

Weakness

  • CWE-787: Out-of-bounds Write

Source file

pypi/Pillow/CVE-2026-128067.yml

Spotted a mistake? Edit the file on GitLab.

  • Site Repo
  • About GitLab
  • Terms
  • Privacy Statement
  • Contact

Page generated Fri, 13 Nov 2026 12:17:45 +0000.