A PNG's EXIF chunk makes parsing take quadratic time
A PNG eXIf chunk full of repeated six-byte markers makes Exif.load() copy the buffer once per marker.
- Advisory
- CVE-2026-96643 (also GHSA-g4qv-2jxx-769h)
- Library
- Pillow, pillow on PyPI
- Published
- Severity
- 7.1 out of 10, as published
- Affected
- >= 11.0.0, < 13.0.0
- Fixed in
- 13.0.0
- Reaches you
- by opening a file
What triggers it
Opening a PNG and reading its EXIF (getexif()) when the eXIf chunk is large and filled with repeated markers. The advisory says a photo-sized file is enough.
What sillybos does
Refused by default
sillybos refuses the triggering file under its default policy, through the max_metadata_bytes check.
The size of every PNG chunk other than image data is read before decoding and held to max_metadata_bytes (4 MiB by default, 1 MiB strict). That bounds the cost; it does not remove it, since a chunk under the limit still costs seconds.
Bounded, not closed: the limit turns an unbounded cost into a bounded one.
Proved by these tests in the sillybos suite, each of which builds the triggering file from bytes and checks that it is refused:
tests/test_check.py::TestHostileFiles::test_a_png_with_an_enormous_exif_chunktests/test_check.py::TestHostileFiles::test_strict_allows_less_metadata
How to protect yourself
In general. Upgrade to Pillow 13.0.0.
Specifically. Cap metadata blocks well below what a scan carries (kilobytes): sillybos --max-metadata-bytes.
The general advice applies to every row here.
Sources
- https://github.com/advisories/GHSA-g4qv-2jxx-769h
- The record entry, triaged 2026-11-01, last checked 2026-11-01