High

Pillow JPEG2000 tiled decode retains a growing scratch buffer and can be used for denial of service

  • Disclosed: 20.07.2026
  • Updated: 11.10.2026 15:17

Summary

src/libImaging/Jpeg2KDecode.c:853 accumulates total_component_width across every tile in a JPEG2000 image instead of recomputing it per tile. That accumulated value is then used in the tile_bytes calculation at src/libImaging/Jpeg2KDecode.c:868, which can make the decoder grow state->buffer via realloc at src/libImaging/Jpeg2KDecode.c:876 up to roughly one full image's decompressed size even when each tile is small. A crafted tiled JPEG2000 file can therefore force substantially higher transient memory usage and trigger out-of-memory failures during decoding. Based on current evidence, the supported impact is denial of service, not memory corruption.

Details

  • Location: src/libImaging/Jpeg2KDecode.c:853
  • Root cause: total_component_width is initialized only once before the tile loop and keeps growing across tiles. It is then used to derive tile_bytes, so later tiles are treated as if they had the combined component width of all earlier tiles.
  • Dangerous operation: tile_bytes is promoted into tile_info.data_size, then state->buffer is grown with realloc at src/libImaging/Jpeg2KDecode.c:876.
  • Reachability: any attacker-controlled JPEG2000 image with many tiles reaches this path during normal Image.open(...).load() decoding.

PoC

The attached helper script and testcase were used: exercise_j2k_tile_realloc.zip

Generate the testcase:

bash
pythonexercise_j2k_tile_realloc.py make poc_3664_rgba_tile1832.jp2 \
  --size 3664 --tile 1832

Expected geometry from the helper:

  • image size: 3664 x 3664
  • mode: RGBA
  • tile size: 1832 x 1832 (2x2 tiles)
  • image_bytes=53699584
  • uncapped RSS observed:
    • vulnerable build: maxrss_kb=180264
    • fixed comparison build: maxrss_kb=138404

Load it with the current vulnerable build:

bash
python exercise_j2k_tile_realloc.py load poc_3664_rgba_tile1832.jp2

Load it again under a 160 MB address-space cap:

bash
python exercise_j2k_tile_realloc.py load poc_3664_rgba_tile1832.jp2 --limit-mb 160

Impact

Conservative impact: denial of service through memory exhaustion during JPEG2000 decoding.

Affected software

Click a technology to see all vulnerabilities affecting it.

PlatformPackageVulnerable versionsFixed in
Python (PyPI) pillow >= 8.2.0, < 12.3.0 12.3.0

References

CVSS score -
CVSS vector
CVSS:4.0/AV:N/AC:L/AT:N/PR:N/UI:N/VC:N/VI:N/VA:H/SC:N/SI:N/SA:N
Weakness (CWE)
CWE-770, CWE-789
Platform
Python (PyPI)
Package
pillow
Disclosed
20.07.2026
Updated
11.10.2026 15:17

Sources and licenses

OSV / GitHub Advisory Database - PYSEC-2026-3496 - PyPA Advisory Database; CC BY 4.0

OSV / GitHub Advisory Database - GHSA-vjc4-5qp5-m44j - CC BY 4.0

Vulnerability history: pillow

All published vulnerabilities of this package (Python (PyPI)), newest first. Shows whether this is a one-off slip or a package that needs watching.

All (81) in the archive
Total entries
81
First → latest
04.2014 10.2026
Without a fix
0
Exploited in attacks
1

Severity breakdown

  • Critical 10
  • High 53
  • Medium 16
  • Low 1
  • Unrated 1

Disclosures per year

  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: 23

earlier: 12

Severity:
  1. Pillow JPEG2000 tiled decode retains a growing scratch buffer and can be used for denial of service this entry
    High CVE-2026-59204 >= 8.2.0, < 12.3.0 12.3.0
  2. High · 7.5 CVE-2026-59200 >= 5.1.0, < 12.3.0 12.3.0
  3. High CVE-2026-42311 >= 10.3.0, < 12.2.0 12.2.0
  4. High · 7.5 CVE-2026-40192 >= 10.3.0, < 12.2.0 12.2.0
  5. High CVE-2026-25990 >= 10.3.0, < 12.1.1 12.1.1
  6. High · 7.1 CVE-2025-48379 >= 11.2.0, < 11.3.0 11.3.0
  7. High · 6.7 CVE-2024-28219 < 10.3.0 10.3.0
  8. Critical · 8.1 CVE-2023-50447 < 10.2.0 10.2.0
  9. High · 8.8 Exploited in attacks CVE-2023-4863 < 10.0.1 10.0.1
  10. High · 7.5 CVE-2022-45199 >= 9.2.0, < 9.3.0 9.3.0
  11. High · 7.5 CVE-2022-30595 >= 9.1.0, < 9.1.1 9.1.1
  12. High · 9.1 CVE-2022-24303 < 9.0.1 9.0.1
  13. Critical · 9.8 CVE-2022-22817 < 9.0.1 9.0.1
  14. High · 7.5 CVE-2021-23437 >= 5.2.0, < 8.3.2 8.3.2
  15. Critical · 9.8 CVE-2021-34552 < 8.3.0 8.3.0
  16. High · 7.5 CVE-2021-28677 < 8.2.0 8.2.0
  17. High · 7.5 CVE-2021-28676 < 8.2.0 8.2.0
  18. High · 9.1 CVE-2021-25288 >= 2.4.0, < 8.2.0 8.2.0
  19. High · 9.1 CVE-2021-25287 >= 2.4.0, < 8.2.0 8.2.0
  20. High · 5.5 CVE-2021-28675 < 8.2.0 8.2.0
  21. High · 7.5 CVE-2021-25293 >= 4.3.0, < 8.1.1 8.1.1
  22. High · 7.5 CVE-2021-25291 < 8.2.0 8.2.0
  23. High · 7.5 CVE-2021-25290 < 8.1.1 8.1.1
  24. Critical · 9.8 CVE-2021-25289 < 8.1.1 8.1.1
  25. High · 7.5 CVE-2021-27923 < 8.1.2 8.1.2
  26. High · 7.5 CVE-2021-27922 < 8.1.2 8.1.2
  27. High · 7.5 CVE-2021-27921 < 8.1.2 8.1.2
Show more (20) Showing 40 of 63

Know which vulnerabilities affect your application

With the DockRay integration and software inventory enabled, DockRay checks reported component versions against known vulnerabilities and notifies you about confirmed matches. Coverage depends on the supported technology and available advisory data.

Connect your application
DockRay newsletter

Application security in your inbox

Important vulnerabilities, actionable guidance and practical advice for your applications. Choose your technologies and follow what matters to your project.

  • A daily digest of new vulnerabilities, critical ones included.
  • Notifications about important updates.
  • Practical advice on application security and monitoring.

Leave empty to receive updates for every technology.

Free to subscribe. Unsubscribe with one click in any email.