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

CVE-2026-128066: Pillow: Memory DoS in TIFF and EXIF IFD parsing via overlapping tag data

November 12, 2026

============================================================================
ANT-2026-D7STJUWL  [medium]  CWE-770  dos
Memory DoS in TIFF and EXIF IFD parsing via overlapping tag data
Location: src/PIL/TiffImagePlugin.py:927  in ImageFileDirectory_v2.load()
Commit:   a707c6b21c313880d0771e54965d142dd42358b6
============================================================================

A small, crafted image file can make Pillow use thousands of times its own size in memory while the file is only being opened, which lets anyone who can submit an image crash or stall the process handling it. A 144 KB TIFF makes Image.open() return normally while holding 1.6 GiB of memory. The largest such standard TIFF, about 786 KB, asks for roughly 48 GiB, which in practice gets the worker killed by the operating system. The file declares a 1×1 image, so the decompression-bomb check never triggers and no warning is raised. There is no memory corruption; the impact is denial of service.

The bug is in ImageFileDirectory_v2.load() in src/PIL/TiffImagePlugin.py (around line 927). For every directory entry whose value is stored elsewhere in the file, it reads that value into a new bytes object with ImageFile._safe_read(fp, count * unit_size) and keeps it in _tagdata. _safe_read() only checks that the bytes exist. Nothing limits the total read across entries, and nothing stops every entry from pointing at the same bytes. An attacker can therefore give each of N distinct private tags an offset and count that covers the whole file, at a cost of 12 bytes per entry. Memory grows as N × file size, which is quadratic in the file size, and BigTIFF removes the 65,535-entry ceiling.

The same loop parses EXIF data, so the problem reaches beyond TIFF:

  • A 66 KB JPEG APP1 segment costs about 340 MiB inside Image.open() itself, via _read_dpi_from_exif().
  • A 96 KB PNG eXIf chunk costs 754 MiB on getexif() or ImageOps.exif_transpose().
  • WebP EXIF and MPO reach the same code.

The attached reproducer builds a 72 KB TIFF and a 72 KB PNG. Using only Image.open() and getexif(), each causes 412 MiB of tag data to be retained, about 6,000 times the file size. The loop dates to the original PIL 1.1.7 import, so every Pillow release since 1.0 is affected.

References

  • github.com/advisories/GHSA-wqgw-9xfh-qf2g
  • github.com/python-pillow/Pillow/commit/4908edaf7f416616784c7c03d8c1a60153710ffb
  • github.com/python-pillow/Pillow/commit/4b63dffd8a6d980fa0e21b40832fa6cbf033eacf
  • github.com/python-pillow/Pillow/releases/tag/13.0.0
  • github.com/python-pillow/Pillow/security/advisories/GHSA-wqgw-9xfh-qf2g
  • nvd.nist.gov/vuln/detail/CVE-2026-128066

Code Behaviors & Features

Detect and mitigate CVE-2026-128066 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.

Weakness

  • CWE-770: Allocation of Resources Without Limits or Throttling

Source file

pypi/Pillow/CVE-2026-128066.yml

Spotted a mistake? Edit the file on GitLab.

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

Page generated Fri, 13 Nov 2026 12:15:48 +0000.