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

CVE-2026-112390: Pillow Python Library DOS Vulnerability

CVE-2026-112390 is a denial of service flaw in Pillow Python imaging library that causes infinite loops when processing crafted MIC files. This post explains its impact, affected versions, and mitigation steps.

Published:

CVE-2026-112390 Overview

CVE-2026-112390 is a denial-of-service vulnerability in Pillow, the widely used Python imaging library. Affected versions from 7.2.0 up to (but not including) 13.0.0 can enter an infinite loop when determining the frame count of a crafted MIC (Microsoft Image Composer) image. The MicImageFile class inherits TIFF frame traversal, but its tell method reports the OLE stream index while seek() resets TIFF frame state. An embedded TIFF with at least three Image File Directories (IFDs) never advances, causing non-terminating iteration. Applications with olefile installed that read n_frames or save all frames from a crafted MIC file can pin a worker at full CPU indefinitely.

Critical Impact

Remote attackers can submit a crafted MIC file to any Pillow-backed image processing service with olefile installed, causing sustained CPU exhaustion on worker threads and denial of service.

Affected Products

  • Pillow versions 7.2.0 through 12.x (any release prior to 13.0.0)
  • Python applications using MicImageFile with the olefile dependency installed
  • Image processing pipelines invoking n_frames or save_all on untrusted MIC input

Discovery Timeline

  • 2026-10-19 - CVE-2026-112390 published to NVD
  • 2026-10-20 - Last updated in NVD database

Technical Details for CVE-2026-112390

Vulnerability Analysis

The vulnerability is an infinite loop condition [CWE-835] in Pillow's MicImageFile plugin. MIC files are OLE compound documents that embed TIFF streams. MicImageFile inherits frame traversal logic from TiffImageFile, but overrides tell() and seek() to operate on the OLE stream index rather than TIFF IFD offsets. When frame-count determination logic walks IFDs through seek(), each call resets TIFF frame state back to the first IFD. The traversal never terminates when the embedded TIFF contains three or more IFDs.

Root Cause

The root cause is a semantic mismatch between inherited TIFF frame iteration and the overridden MicImageFile positioning methods. MicImageFile.tell returns an OLE stream index, while the parent class expects a TIFF frame index. Because seek() resets TIFF state on every call, the loop condition that would normally advance past the final IFD can never be satisfied. The patch introduces an explicit _n_frames initializer in TiffImageFile.__init__ so that MicImageFile no longer inherits mutable TIFF frame counting state.

Attack Vector

Exploitation requires an attacker to submit a crafted MIC file to any application that processes untrusted images with Pillow and has olefile installed. Triggering code paths include reading the n_frames attribute or calling save(..., save_all=True). No authentication or user interaction is required beyond submitting the malicious image. Each processed file ties up one worker at 100% CPU until the process is killed, enabling low-cost denial of service against image-handling web services.

python
# Patch excerpt from src/PIL/TiffImagePlugin.py
# Source: https://github.com/python-pillow/Pillow/commit/26cb3ed061173b817b9ee4b6f507cb0e1e293218
        self.tag: ImageFileDirectory_v1
        """ Legacy tag entries """

        self._n_frames: int | None = None
        super().__init__(fp, filename)

    def _open(self) -> None:

The fix initializes _n_frames on the TiffImageFile instance before calling the superclass constructor, preventing MicImageFile from inheriting state that drives the non-advancing traversal.

Detection Methods for CVE-2026-112390

Indicators of Compromise

  • Python worker processes sustained at 100% CPU with stack frames inside PIL.TiffImagePlugin or PIL.MicImagePlugin.
  • Image processing queues backing up or timing out shortly after a MIC (.mic) file upload.
  • Repeated submissions of OLE compound files with .mic extensions or MIC magic bytes from a single source.

Detection Strategies

  • Inventory Python environments and identify services running Pillow versions >=7.2.0,<13.0.0 with olefile installed.
  • Instrument image parsers with per-file processing timeouts and alert on files that exceed the threshold.
  • Monitor for process-level CPU saturation on worker pods or containers that handle user-supplied images.

Monitoring Recommendations

  • Log the file type, source IP, and processing duration for every image handled by Pillow-backed endpoints.
  • Alert on repeated MIC uploads or on any upload that triggers a timeout in the image processing pipeline.
  • Track dependency inventories so that newly introduced olefile installations into Pillow environments surface for review.

How to Mitigate CVE-2026-112390

Immediate Actions Required

  • Upgrade Pillow to version 13.0.0 or later across all applications and container images.
  • Enforce request-level and per-image processing timeouts on any endpoint that accepts user-supplied images.
  • Audit production dependencies to identify every service that bundles both Pillow and olefile.

Patch Information

The issue is fixed in Pillow 13.0.0. The upstream fix is tracked in GitHub Security Advisory GHSA-22hg-r758-rrw9 and applied in this Pillow commit. Release notes are available in the Pillow 13.0.0 release.

Workarounds

  • Uninstall olefile from environments that do not require OLE compound document support; MicImageFile is only registered when olefile is available.
  • Reject MIC images and other OLE compound documents at the application boundary when they are not an expected input format.
  • Isolate image processing in short-lived worker processes with hard CPU and wall-clock limits so a single malicious file cannot exhaust shared capacity.
bash
# Upgrade Pillow to the fixed release
pip install --upgrade "Pillow>=13.0.0"

# Optional: remove olefile where OLE/MIC support is not required
pip uninstall -y olefile

# Verify 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.