Pillow-Mehrbild-Loader können nach Moduswechseln veralteten nativen Bildspeicher wiederverwenden
Zusammenfassung
Mehrbild-Bild-Loader in Pillow können den nativen Speicher ImagingCore, der für ein Frame reserviert wurde, beibehalten, während das Python-seitige Bild-mode und die Decoder-Kacheln für ein nachfolgendes Frame geändert werden.
Wenn Frame 0 Speicher für einen schmaleren Modus wie L reserviert und ein nachfolgendes Frame mit denselben Abmessungen zu einem breiteren Modus wie RGB oder CMYK wechselt, dekodiert Pillow möglicherweise breitere Pixel in den veralteten schmaleren nativen Puffer. Dies verursacht native Out-of-bounds-Schreibvorgänge und Prozessabstürze. Im MPO/JPEG-Pfad wurde zudem eine Befehlsausführung in passenden Python/Pillow-Laufzeitprofilen über den dokumentierten Pfad ImageSequence.Iterator + frame.load() nachgewiesen.
Details
Die Ursache liegt offenbar darin, dass ImageFile.load_prepare() den nativen Speicher nur neu zuweist, wenn _im is None. Es wird nicht überprüft, ob der beibehaltene native Speicher ImagingCore weiterhin mit self.mode und self.size übereinstimmt.
Mehrere Mehrbild-Pfade von seek() / _open() können self._mode und die Decoder-Kacheln für ein späteres Frame aktualisieren, ohne _im zu invalidieren. Der Decoder schreibt oder liest dann entsprechend dem neuen Frame-Modus, während der native Speicher noch dem vorherigen Frame-Modus zugeordnet ist.
Verifizierte betroffene Angriffsflächen:
-
PSD
PsdImageFile.seek()kann von Graustufen/nativemL-Speicher zur RGB-Ebenendekodierung wechseln, während_imbeibehalten wird. Dies führt zu angreifergesteuerten nativen Out-of-bounds-Schreibvorgängen und zuverlässigen Abstürzen. -
MPO/JPEG Eine manipulierte Zwei-Frame-MPO-Datei kann dazu führen, dass Frame 0 Speicher für
Lreserviert und anschließend Frame 1 Daten vom TypCMYK/RGBin den beibehaltenenL-Speicher dekodiert. Der dokumentierte PfadImageSequence.Iteratorerreicht dies überframe.load(). Verifiziert wurden native Speicherbeschädigung, Abstürze, Over-Read-Verhalten sowie eine abgegrenzte Marker-Befehlsausführung unter Pillow 12.3.0. -
DCX
DcxImageFile.seek()ruftPcxImageFile._open()auf, was den Modus-/Kachelstatus ohne Prüfung des nativen Speichermodus ändert. Ein manipuliertes DCX mitL- und anschließendRGB-PCX-Frames führt zu einer Nichtübereinstimmung des beibehaltenen Speichers und zum Absturz. -
MIC MIC kann
TiffImageFile._open()direkt aufrufen und das normale abgesicherteseek()-Verhalten von TIFF umgehen. Bei einem erreichbaren Frame-Übergang auf Basis vonNextIFDführt dies zu einer Nichtübereinstimmung des Speichers und zum Absturz.
TIFF stellt eine nützliche Positivkontrolle dar, da der Pfad seek() sowohl Größe als auch Modus vor der Wiederverwendung des Speichers überprüft.
Auswirkungen
- Prozessabsturz / Denial of Service
- Nativer Out-of-bounds-Schreibvorgang
- Nativer Over-Read im MPO-Pfad
- Befehlsausführung in kompatiblen Python/Pillow-Laufzeitumgebungen über den MPO/JPEG-Pfad
Auswirkungen im Serverbetrieb:
- In einem lokalen anfälligen Web-Upload-Dienst, der nicht authentifizierte MPO-Uploads annimmt und automatisch mit Pillow verarbeitet, genügt eine einzelne HTTP-Anfrage ohne weitere Benutzerinteraktion.
- Der feste Marker zur Befehlsausgabe war in 10 von 10 Fällen erfolgreich.
- Der Kontrolllauf
_im=Noneblieb in 10 von 10 Fällen unauffällig.
Reproduktionsbelege
Getestete Version:
Pillow 12.3.0
MPO-Terminal-Prüfumgebungen:
Python 3.12.3 + Pillow 12.3.0, clean PyPI environment:
marker 10/10, control 0/10
Python 3.13.14 + Pillow 12.3.0, prepared profile:
marker 10/10, control 0/10
Server-Web-Upload-Nachweis:
control 1..10: MARKER_MISSING
control_summary ok 0 missing 10 /10
vulnerable 1..10: MARKER_OK marker_output <server-user>
vulnerable_summary ok 10 missing 0 /10
Der Terminalnachweis verwendet ausschließlich einen festen, harmlosen Marker-Befehl und keine Reverse-Shell, Persistenz, Datenexfiltration oder frei wählbare Befehle.
Folgende Artefakte können Maintainern bereitgestellt werden:
- Minimale Crash-Fixtures für PSD, MPO, DCX und MIC
- Nicht waffenfähiger MPO-Marker-PoC
- Lokale anfällige Web-Upload-Demo
- gdb/GEF-Geometriebelege
- Kontrolllauf-Protokolle
- Vorgeschlagene Regressionstest-Struktur
Minimale Reproduktionsstruktur
Für den MPO-Pfad lautet die verwundbare Struktur:
from io import BytesIO
from PIL import Image, ImageSequence
source = BytesIO(open(path, "rb").read())
image = Image.open(source)
iterator = ImageSequence.Iterator(image)
next(iterator).load()
next(iterator).load()
Die manipulierte Bildstruktur:
frame 0: mode L, dimensions W x H
frame 1: same W x H, wider mode such as CMYK
Frame 0 reserviert nativen Speicher für L. Frame 1 ändert den logischen Modus und den Decoder-Status, kann jedoch den alten nativen Speicher wiederverwenden. Der Decoder für Frame 1 schreibt dann mit dem breiteren Modus in den schmaleren Speicher.
Lösungsvorschlag
Vor der Wiederverwendung des nativen Speichers ImagingCore sollte Pillow überprüfen, ob der beibehaltene Speicher mit dem aktuellen logischen Bildmodus und der Bildgröße kompatibel ist.
Eine zentrale Prüfung in ImageFile.load_prepare() könnte Modus und Größe des nativen Speichers mit self.mode / self.size vergleichen und neuen Speicher zuweisen, wenn Abweichungen vorliegen. Alternativ sollte jeder modusändernde Pfad von seek() / _open() den Speicher _im vor der Dekodierung explizit invalidieren.
Hinweis: TIFF verfügt über ein spezialisiertes Verhalten bezüglich Kachelgrößen und besitzt bereits eine Modus-/Größenprüfung; ein zentraler Fix sollte dieses Verhalten nicht beeinträchtigen.
Danksagung
Rotem Kama
Hinweis zur Methodik
Für die Entdeckung und Verifizierung wurde KI-gestützte Analyse eingesetzt. Die Angaben in diesem Bericht beschränken sich auf die oben genannten Artefakte, Kontrollen und Befehlsausgaben.
Was zu tun ist
Aktualisieren Sie Pillow auf Version 13.0.0 oder höher.
Betroffene Software
Klicken Sie auf eine Technologie, um alle zugehörigen Schwachstellen anzuzeigen.
| Plattform | Paket | Anfällige Versionen | Behoben in |
|---|---|---|---|
| Python (PyPI) | pillow | >= 11.0.0, < 13.0.0 | 13.0.0 |
Verweise
- https://github.com/python-pillow/Pillow/security/advisories/GHSA-v9pv-5gc8-w2m6
- https://nvd.nist.gov/vuln/detail/CVE-2026-96639
- https://github.com/python-pillow/Pillow/pull/10105
- https://github.com/python-pillow/Pillow/commit/78d97d994579aef81aafe123773d525f40f2522a
- https://github.com/python-pillow/Pillow
- https://github.com/python-pillow/Pillow/releases/tag/13.0.0
- CVSS-Vektor
CVSS:3.1/AV:N/AC:L/PR:N/UI:N/S:U/C:H/I:H/A:H- Schwäche (CWE)
CWE-125, CWE-787- Plattform
- Python (PyPI)
- Paket
pillow- Veröffentlicht
- 22.10.2026
- Aktualisiert
- 23.10.2026 00:03
Quellen und Lizenzen · Von DockRay bearbeitet oder übersetzt; Rechte und Lizenzen der Quellen bleiben erhalten.
OSV / GitHub Advisory Database - GHSA-v9pv-5gc8-w2m6 - CC BY 4.0
Schwachstellenhistorie: pillow
Alle veröffentlichten Schwachstellen dieses Pakets (Python (PyPI)), neueste zuerst. Zeigt, ob es ein einmaliger Ausrutscher ist oder ein Paket, das man im Auge behalten muss.
- Einträge insgesamt
- 100
- Erste → letzte
- 04.2014 10.2026
- Ohne Fix
- 0
- In Angriffen ausgenutzt
- 1
Verteilung nach Schweregrad
- Kritisch 13
- Hoch 58
- Mittel 27
- Niedrig 1
- Nicht bewertet 1
Veröffentlichungen pro Jahr
- 2017: 1
- 2018: 0
- 2019: 1
- 2020: 10
- 2021: 20
- 2022: 8
- 2023: 3
- 2024: 2
- 2025: 1
- 2026: 42
früher: 12
-
Pillow-Mehrbild-Loader können nach Moduswechseln veralteten nativen Bildspeicher wiederverwenden dieser Eintrag
Erkennen Sie Schwachstellen in Ihrer Anwendung
Mit der DockRay-Integration und aktivierter Softwareinventarisierung prüft DockRay gemeldete Komponentenversionen auf bekannte Schwachstellen und benachrichtigt Sie über bestätigte Treffer. Die Abdeckung hängt von der unterstützten Technologie und den verfügbaren Meldungen ab.