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

CVE-2026-112400: Pillow Python Library DOS Vulnerability

CVE-2026-112400 is a denial of service vulnerability in Pillow Python imaging library that allows attackers to exhaust memory through crafted GIF files. This post explains its technical details, affected versions, and mitigation steps.

Published:

CVE-2026-112400 Overview

CVE-2026-112400 is a denial-of-service vulnerability in Pillow, the widely used Python imaging library. The flaw affects versions 9.2.0 through 13.0.0 and resides in the GIF image handler. Specifically, GifImageFile._seek retains rejected frame dimensions after a DecompressionBombError is raised. Applications that catch the exception and continue to use the same image object trigger memory allocation based on the attacker-controlled dimensions during subsequent seek or load calls. This behavior enables resource exhaustion [CWE-400] against any service that processes untrusted GIF input.

Critical Impact

Remote attackers can exhaust process memory and deny service by submitting a crafted GIF to any Pillow-based image pipeline that catches DecompressionBombError and continues processing.

Affected Products

  • Pillow versions 9.2.0 through 12.x
  • Python applications and web services using Pillow for GIF processing
  • Downstream frameworks that catch Image.DecompressionBombError and reuse the image object

Discovery Timeline

  • 2026-10-19 - CVE-2026-112400 published to NVD
  • 2026-10-20 - Last updated in NVD database
  • Pillow 13.0.0 - Fix released by the python-pillow maintainers

Technical Details for CVE-2026-112400

Vulnerability Analysis

The vulnerability lives in src/PIL/GifImagePlugin.py inside the _seek method. When Pillow parses a GIF frame, it computes the maximum extent of the image by taking the largest of the current size and the new frame bounds. The pre-patch code assigned the new dimensions to self._size before calling Image._decompression_bomb_check. If the bomb check raised DecompressionBombError, control left the function, but the oversized dimensions were already persisted on the image object.

Any caller that wraps seek or load in a try/except DecompressionBombError block and then reuses the same Image instance causes Pillow to allocate buffers sized to the rejected dimensions on later operations. A crafted multi-frame GIF with frames declaring extents far beyond the logical screen descriptor is enough to force gigabytes of allocation per request.

Root Cause

The root cause is an ordering defect: state mutation occurs before validation. The decompression-bomb check is intended to reject malicious dimensions, but because self._size is updated prior to the check, the rejection does not roll back the object state. This violates the invariant that self._size only ever holds validated dimensions.

Attack Vector

Exploitation requires only that an attacker-controlled GIF reaches a Pillow-based pipeline that tolerates DecompressionBombError. Common targets include image upload endpoints, thumbnail generators, content moderation pipelines, and document conversion services. No authentication or user interaction is required when the processing endpoint is network-reachable.

python
                 x0, y0 = i16(s, 0), i16(s, 2)
                 x1, y1 = x0 + i16(s, 4), y0 + i16(s, 6)
                 if (x1 > self.size[0] or y1 > self.size[1]) and update_image:
-                    self._size = max(x1, self.size[0]), max(y1, self.size[1])
-                    Image._decompression_bomb_check(self._size)
+                    size = max(x1, self.size[0]), max(y1, self.size[1])
+                    Image._decompression_bomb_check(size)
+                    self._size = size
                 frame_dispose_extent = x0, y0, x1, y1
                 flags = s[8]

Source: GitHub Pillow Commit 6faed70. The patch computes the candidate size into a local variable, validates it, and only then commits it to self._size.

Detection Methods for CVE-2026-112400

Indicators of Compromise

  • Repeated PIL.Image.DecompressionBombError entries in application logs followed by continued processing of the same request.
  • Image-processing worker processes terminated by the OS out-of-memory killer shortly after GIF ingestion.
  • Inbound GIF uploads whose logical screen descriptor conflicts sharply with per-frame extents.

Detection Strategies

  • Inventory Python dependencies and flag any service using Pillow between 9.2.0 and 12.x inclusive.
  • Instrument image handlers to log the file hash, declared dimensions, and exception type for every DecompressionBombError.
  • Correlate upload endpoint traffic with sudden resident-memory growth or worker restarts to identify active abuse.

Monitoring Recommendations

  • Enforce per-request memory and CPU limits on image-processing workers using cgroups or container resource caps.
  • Alert when a single client submits multiple GIFs that trigger DecompressionBombError in a short window.
  • Track Pillow version strings via software composition analysis to catch regressions after deploys.

How to Mitigate CVE-2026-112400

Immediate Actions Required

  • Upgrade Pillow to version 13.0.0 across all production and build environments.
  • Audit application code for except DecompressionBombError handlers that continue to use the same Image object, and discard the object instead.
  • Rate-limit anonymous image upload endpoints and cap maximum accepted file size for GIF content.

Patch Information

The fix is included in Pillow 13.0.0. See the GitHub Security Advisory GHSA-65qm-jvmh-6pqg and the Pillow 13.0.0 release notes. The upstream commit 6faed70 reorders the size assignment so self._size is only mutated after the bomb check succeeds.

Workarounds

  • If upgrading is not immediately possible, lower Image.MAX_IMAGE_PIXELS and treat DecompressionBombError as fatal by closing and discarding the image object.
  • Pre-validate GIF headers out-of-band and reject files whose declared dimensions exceed service policy before passing them to Pillow.
  • Isolate image decoding in short-lived subprocess workers with hard memory ulimits so an exhaustion attempt cannot affect the parent service.
bash
# Upgrade Pillow to the fixed 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.

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.