CVE-2026-96636
### Summary Pillow's decompression-bomb protection (`Image._decompression_bomb_check`, gated by `Image.MAX_IMAGE_PIXELS`) is enforced only on the **first frame**, inside `Image.open()`. For multi-frame formats, `seek()` re-parses the target frame's header and resets `self._size`. `GifImagePlugin` and `TiffImagePlugin` re-run the bomb check on `seek()`, but **`MpoImageFile.seek()` and `DcxImageFile.seek()` do not.** A crafted MPO or DCX whose first frame is tiny (passing the check) but whose later frame declares enormous dimensions therefore bypasses the protection: loading that frame decodes an over-limit image and commits large amounts of memory — a denial of service (memory exhaustion / OOM). Same class as the recently assigned CVE-2026-55379 (BdfFontFile), CVE-2026-55380 (GdImageFile) and CVE-2026-40192 (FITS GZIP). ### Details `Image.open()` → `_open_core()` runs `_decompression_bomb_check(im.size)` once, on the frame present at open time. Both vulnerable `seek()` methods re-parse a new frame and set a new `self._size` without re-checking: - **`PIL/MpoImagePlugin.py`, `MpoImageFile.seek()`**: calls `JpegImagePlugin.JpegImageFile._open(self)` (which sets `self._size` from the frame's JPEG SOF) and rebuilds `self.tile`, with no `Image._decompression_bomb_check(self.size)`. - **`PIL/DcxImagePlugin.py`, `DcxImageFile.seek()`**: calls `PcxImageFile._open(self)` (which sets `self._size` from the page's PCX header), with no check. Confirmed present in **12.3.0** (latest release) and on **`main`** (13.0.0.dev0). Compare `GifImagePlugin._seek` and `TiffImagePlugin`, which call `_decompression_bomb_check` correctly on seek. ### PoC Self-contained; the victim uses **default** `MAX_IMAGE_PIXELS`: ```python import io from PIL import Image # attacker builds the file (guard disabled only to CREATE the oversized frame) Image.MAX_IMAGE_PIXELS = None small = Image.new("RGB", (8, 8)) big = Image.new("RGB", (14000, 14000), (120, 60, 30)) # 196,000,000 px > error threshol
Properties
- Severity
- medium
- Summary
- Pillow: Decompression-bomb protection bypass via multi-frame seek() in MPO and DCX (MpoImageFile.seek / DcxImageFile.seek)
- Nvd fetched at
- 2026-10-22T22:14:18.200859+00:00
- Epss score
- 0.0028
- Cvss severity
- MEDIUM
- Cvss score
- 6.5
- Retrieved at
- 2026-10-22T22:17:36+00:00
- Ghsa published
- 2026-10-22T15:56:37Z
- Source url
- https://github.com/advisories/GHSA-p8hx-v2p6-rp84
- Ghsa updated
- 2026-10-22T15:56:39Z
- Ghsa id
- GHSA-p8hx-v2p6-rp84
- Last source
- FIRST EPSS
- Score
- 6.5
- Cvss version
- 3.1
- Cve id
- CVE-2026-96636
- Cvss vector
- CVSS:3.1/AV:N/AC:L/PR:N/UI:R/S:U/C:N/I:N/A:H
- First seen by Signal
- 2026-10-21T22:34:38+00:00
- Is ghsa only
- false
- Vector
- CVSS:3.1/AV:N/AC:L/PR:N/UI:R/S:U/C:N/I:N/A:H
- Published at
- 2026-10-21T21:20:31.760
Related Entities (4)
HAS_WEAKNESS (2)
AFFECTS (1)
VULNERABLE_TO (1)
Explore deeper with Ninja Signal's threat intelligence graph