A lossless JPEG overruns the decode buffer when scaled
Heap buffer overflow in ImagingJpegDecode: a lossless (SOF3) frame ignores the requested scaling and writes full-width rows into a buffer sized for the scaled width.
- Advisory
- CVE-2026-112403 (also GHSA-8g5g-8vmr-9782)
- Library
- Pillow, pillow on PyPI
- Published
- Severity
- 9.2 out of 10, as published
- Affected
- <= 12.3.0
- Fixed in
- 13.0.0
- Reaches you
- by opening a file
What triggers it
A standards-compliant lossless JPEG, opened and then drafted or thumbnailed (Image.thumbnail() does this on its own). The advisory notes that formats=["JPEG"] does not prevent it.
What sillybos does
Refused by default
sillybos refuses the triggering file under its default policy, through the jpeg_frames check.
The frame coding is read from the JPEG's frame header. The default policy allows baseline, extended and progressive frames only; a lossless frame is refused with the coding named.
Proved by this test in the sillybos suite, which builds the triggering file from bytes and checks that it is refused:
How to protect yourself
In general. Upgrade to Pillow 13.0.0. Call load() before thumbnail(), or pass reducing_gap=None, until then.
Specifically. Refuse frame codings a scanner never writes: lossless, hierarchical, arithmetic. sillybos does this by default.
The general advice applies to every row here.
Sources
- https://github.com/advisories/GHSA-8g5g-8vmr-9782
- The record entry, triaged 2026-11-01, last checked 2026-11-01