Krytyczna

Moduły ładowania obrazów wieloklatkowych Pillow mogą ponownie wykorzystać nieaktualną pamięć natywną po zmianie trybu

  • Ujawniono: 22.10.2026
  • Aktualizacja: 23.10.2026 10:00

Podsumowanie

Moduły ładowania obrazów wieloklatkowych w bibliotece Pillow mogą zachowywać pamięć natywną ImagingCore przydzieloną dla jednej klatki, podczas gdy po stronie Pythona następuje zmiana trybu obrazu mode oraz kafelków dekodera dla kolejnej klatki.

Jeśli klatka 0 alokuje pamięć dla węższego trybu, takiego jak L, a kolejna klatka o tych samych wymiarach przełącza się na szerszy tryb, taki jak RGB lub CMYK, Pillow może zdekodować szersze piksele do nieaktualnego, węższego bufora natywnego. Prowadzi to do natywnego zapisu poza zakresem i awarii procesu. Na ścieżce MPO/JPEG wykazano również możliwość wykonania poleceń w pasujących środowiskach wykonawczych Python/Pillow za pośrednictwem udokumentowanej ścieżki ImageSequence.Iterator + frame.load().

Szczegóły

Przyczyną problemu jest fakt, że ImageFile.load_prepare() ponownie alokuje pamięć natywną tylko wtedy, gdy _im is None. Nie sprawdza, czy zachowana pamięć natywna ImagingCore nadal odpowiada właściwościom self.mode i self.size.

Wiele ścieżek wieloklatkowych seek() / _open() może aktualizować self._mode i kafelki dekodera dla późniejszej klatki bez unieważniania _im. Dekoder zapisuje lub odczytuje dane zgodnie z nowym trybem klatki, podczas gdy pamięć natywna nadal odpowiada trybowi poprzedniej klatki.

Zweryfikowane podatne komponenty:

  1. PSD PsdImageFile.seek() może przełączyć się ze skali szarości / natywnego bufora L na dekodowanie warstwy RGB przy jednoczesnym zachowaniu _im. Powoduje to kontrolowany przez atakującego natywny zapis poza dozwolonym zakresem i powtarzalną awarię procesu.

  2. MPO/JPEG Odpowiednio spreparowany plik MPO z dwiema klatkami może spowodować alokację pamięci L przez klatkę 0, a następnie dekodowanie danych CMYK / RGB dla klatki 1 do zachowanej pamięci L. Udokumentowana ścieżka ImageSequence.Iterator wywołuje ten stan poprzez frame.load(). Zweryfikowano uszkodzenie pamięci natywnej, awarię, odczyt poza zakresem oraz demonstracyjne wykonanie niegroźnego polecenia znacznika w środowisku Pillow 12.3.0.

  3. DCX DcxImageFile.seek() wywołuje PcxImageFile._open(), co modyfikuje stan trybu/kafelków bez weryfikacji trybu pamięci natywnej. Spreparowany plik DCX z klatkami PCX L, a następnie RGB prowadzi do niezgodności zachowanej pamięci i awarii.

  4. MIC Format MIC może wywołać TiffImageFile._open() bezpośrednio i pominąć standardowe zabezpieczone zachowanie formatu TIFF w seek(). W przypadku osiągalnego przejścia między klatkami opartego na NextIFD skutkuje to niezgodnością pamięci i awarią.

Format TIFF stanowi przydatny punkt odniesienia, ponieważ ścieżka seek() weryfikuje zarówno rozmiar, jak i tryb przed ponownym użyciem pamięci.

Wpływ

  • Awaria procesu / odmowa usługi (DoS)
  • Natywny zapis poza zakresem (out-of-bounds write)
  • Natywny odczyt poza zakresem w ścieżce MPO
  • Wykonanie poleceń w pasujących środowiskach uruchomieniowych Python/Pillow za pośrednictwem ścieżki MPO/JPEG

Wpływ na wdrożenia serwerowe:

  • W lokalnej, podatnej usłudze przesyłania plików, która przyjmuje nieuwierzytelnione pliki MPO i automatycznie przetwarza je przy użyciu Pillow, atak wymaga pojedynczego żądania HTTP i nie wymaga interakcji użytkownika po przesłaniu pliku.
  • Znacznik wykonania nieszkodliwego polecenia powiódł się w 10/10 prób.
  • Przebieg kontrolny _im=None zakończył się poprawnie w 10/10 przypadków.

Dowody reprodukcji

Testowana wersja:

Pillow 12.3.0

Środowiska testowe w terminalu dla MPO:

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

Dowód koncepcji w usłudze przesyłania plików na serwerze:

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

Test w terminalu używa wyłącznie predefiniowanego, nieszkodliwego polecenia-znacznika. Nie korzysta z reverse shella, mechanizmów trwałości, eksfiltracji danych ani dowolnych poleceń zdefiniowanych przez atakującego.

Następujące artefakty mogą zostać udostępnione opiekunom projektu:

  • Minimalne pliki wywołujące awarię dla formatów PSD, MPO, DCX oraz MIC
  • Niezbrojny dowód koncepcji ze znacznikiem MPO
  • Lokalna demonstracja podatnej usługi przesyłania plików
  • Zrzuty geometrii z gdb/GEF
  • Dzienniki przebiegów kontrolnych
  • Proponowany szablon testu regresyjnego

Minimalny schemat reprodukcji

Dla ścieżki MPO podatny kod przyjmuje postać:

python
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()

Struktura spreparowanego obrazu:

frame 0: mode L, dimensions W x H
frame 1: same W x H, wider mode such as CMYK

Klatka 0 alokuje natywną pamięć L. Klatka 1 zmienia tryb logiczny i stan dekodera, lecz może ponownie wykorzystać poprzednią pamięć natywną. Dekoder klatki 1 zapisuje dane w szerszym trybie do węższej pamięci.

Sugerowany kierunek naprawy

Przed ponownym użyciem natywnej pamięci ImagingCore Pillow powinien sprawdzić, czy zachowany bufor jest kompatybilny z bieżącym logicznym trybem i rozmiarem obrazu.

Centralne zabezpieczenie w ImageFile.load_prepare() mogłoby porównywać tryb/rozmiar pamięci natywnej z self.mode / self.size i alokować nową pamięć w przypadku różnic. Alternatywnie każda ścieżka zmieniająca tryb w seek() / _open() powinna jawnie unieważniać _im przed rozpoczęciem dekodowania.

Uwaga: Format TIFF posiada specyficzne zachowanie dotyczące rozmiarów kafelków oraz ma już zabezpieczenie trybu/rozmiaru, dlatego globalna poprawka nie powinna zaburzać obsługi bufora kafelków TIFF.

Podziękowania

Rotem Kama

Uwagi metodologiczne

Do wykrycia i weryfikacji problemu wykorzystano analizę wspomaganą przez sztuczną inteligencję. Wnioski w tym raporcie ograniczają się do lokalnych artefaktów, prób kontrolnych i wyników poleceń opisanych powyżej.

Co trzeba zrobić

Zaktualizuj bibliotekę Pillow do wersji 13.0.0 lub nowszej.

Czego dotyczy

Kliknij technologię, aby zobaczyć wszystkie dotyczące jej podatności.

PlatformaPaczkaPodatne wersjePoprawka w wersji
Python (PyPI) pillow >= 11.0.0, < 13.0.0 13.0.0

Odnośniki

Ocena CVSS 9.8/10
Wektor CVSS
CVSS:3.1/AV:N/AC:L/PR:N/UI:N/S:U/C:H/I:H/A:H
Słabość (CWE)
CWE-125, CWE-787
Platforma
Python (PyPI)
Paczka
pillow
Ujawniono
22.10.2026
Aktualizacja
23.10.2026 10:00

Źródła i licencje · Redakcja lub tłumaczenie: DockRay. Zachowano prawa źródeł i obowiązujące licencje.

OSV / GitHub Advisory Database - GHSA-v9pv-5gc8-w2m6 - CC BY 4.0

Historia podatności: pillow

Wszystkie opisane podatności tej paczki (Python (PyPI)), od najnowszej. Widać, czy to jednorazowa wpadka, czy paczka, której trzeba pilnować.

Wszystkie (100) w archiwum
Wszystkich wpisów
100
Pierwsza → ostatnia
04.2014 10.2026
Bez poprawki
0
Wykorzystywana w atakach
1

Rozkład istotności

  • Krytyczna 13
  • Wysoka 58
  • Średnia 27
  • Niska 1
  • Nieoceniona 1

Ujawnienia w latach

  1. 2017: 1
  2. 2018: 0
  3. 2019: 1
  4. 2020: 10
  5. 2021: 20
  6. 2022: 8
  7. 2023: 3
  8. 2024: 2
  9. 2025: 1
  10. 2026: 42

wcześniej: 12

Istotność:
  1. Moduły ładowania obrazów wieloklatkowych Pillow mogą ponownie wykorzystać nieaktualną pamięć natywną po zmianie trybu ten wpis
    Krytyczna · 9.8 CVE-2026-96639 >= 11.0.0, < 13.0.0 13.0.0
  2. Wysoka CVE-2026-112390 >= 7.2.0, < 13.0.0 13.0.0
  3. Krytyczna CVE-2026-112403 < 13.0.0 13.0.0
  4. Wysoka · 7.5 CVE-2026-59200 >= 5.1.0, < 12.3.0 12.3.0
  5. Wysoka CVE-2026-42311 >= 10.3.0, < 12.2.0 12.2.0
  6. Wysoka · 7.5 CVE-2026-40192 >= 10.3.0, < 12.2.0 12.2.0
  7. Wysoka CVE-2026-25990 >= 10.3.0, < 12.1.1 12.1.1
  8. Wysoka · 7.1 CVE-2025-48379 >= 11.2.0, < 11.3.0 11.3.0
  9. Wysoka · 6.7 CVE-2024-28219 < 10.3.0 10.3.0
  10. Krytyczna · 8.1 CVE-2023-50447 < 10.2.0 10.2.0
  11. Wysoka · 8.8 Wykorzystywana w atakach CVE-2023-4863 < 10.0.1 10.0.1
  12. Wysoka · 7.5 CVE-2022-45199 >= 9.2.0, < 9.3.0 9.3.0
  13. Wysoka · 7.5 CVE-2022-30595 >= 9.1.0, < 9.1.1 9.1.1
  14. Wysoka · 9.1 CVE-2022-24303 < 9.0.1 9.0.1
  15. Krytyczna · 9.8 CVE-2022-22817 < 9.0.1 9.0.1
  16. Wysoka · 7.5 CVE-2021-23437 >= 5.2.0, < 8.3.2 8.3.2
  17. Krytyczna · 9.8 CVE-2021-34552 < 8.3.0 8.3.0
  18. Wysoka · 7.5 CVE-2021-28677 < 8.2.0 8.2.0
  19. Wysoka · 7.5 CVE-2021-28676 < 8.2.0 8.2.0
  20. Wysoka · 9.1 CVE-2021-25288 >= 2.4.0, < 8.2.0 8.2.0
  21. Wysoka · 9.1 CVE-2021-25287 >= 2.4.0, < 8.2.0 8.2.0
  22. Wysoka · 5.5 CVE-2021-28675 < 8.2.0 8.2.0
  23. Wysoka · 7.5 CVE-2021-25293 >= 4.3.0, < 8.1.1 8.1.1
  24. Wysoka · 7.5 CVE-2021-25291 < 8.2.0 8.2.0
  25. Wysoka · 7.5 CVE-2021-25290 < 8.1.1 8.1.1
  26. Krytyczna · 9.8 CVE-2021-25289 < 8.1.1 8.1.1
  27. Wysoka · 7.5 CVE-2021-27923 < 8.1.2 8.1.2
  28. Wysoka · 7.5 CVE-2021-27922 < 8.1.2 8.1.2
  29. Wysoka · 7.5 CVE-2021-27921 < 8.1.2 8.1.2
  30. Wysoka · 8.8 CVE-2020-35654 < 8.1.0 8.1.0
  31. Wysoka · 7.1 CVE-2020-35653 < 8.1.0 8.1.0
  32. Krytyczna · 8.1 CVE-2020-11538 < 7.1.0 7.1.0
  33. Wysoka · 5.5 CVE-2020-10994 < 7.1.0 7.1.0
  34. Wysoka · 5.5 CVE-2020-10177 < 7.1.0 7.1.0
  35. Wysoka · 7.5 CVE-2019-19911 < 6.2.2 6.2.2
  36. Wysoka · 7.1 CVE-2020-5313 < 6.2.2 6.2.2
  37. Krytyczna · 9.8 CVE-2020-5312 < 6.2.2 6.2.2
  38. Krytyczna · 9.8 CVE-2020-5311 < 6.2.2 6.2.2
  39. Krytyczna · 8.8 CVE-2020-5310 < 6.2.2 6.2.2
Pokaż więcej (11) Widać 60 z 71

Dowiedz się, które podatności dotyczą Twojej aplikacji

Po podłączeniu integracji DockRay i włączeniu raportowania oprogramowania DockRay porównuje zgłoszone wersje komponentów ze znanymi podatnościami i powiadamia o potwierdzonych dopasowaniach. Zakres zależy od obsługiwanej technologii i dostępnych biuletynów.

Podłącz swoją aplikację
Newsletter DockRay

Bezpieczeństwo aplikacji w Twojej skrzynce

Najważniejsze podatności, konkretne zalecenia i praktyczne wskazówki dla Twoich aplikacji. Wybierz technologie i śledź to, co ma znaczenie dla Twojego projektu.

  • Codzienne zestawienie nowych podatności, także krytycznych.
  • Powiadomienia o ważnych aktualizacjach.
  • Praktyczne porady o bezpieczeństwie i monitoringu aplikacji.

Pozostaw puste, aby otrzymywać informacje o wszystkich technologiach.

Zapis jest bezpłatny. Wypiszesz się jednym kliknięciem w wiadomości.