CVE-2026-112399: Pillow: APNG background disposal allocates full canvas before decompression bomb check
============================================================================
APNG background disposal allocates full canvas before decompression bomb check
Location: src/PIL/PngImagePlugin.py:1000 in PngImageFile._seek()
Commit: a707c6b21c313880d0771e54965d142dd42358b6
============================================================================
A 126-byte animated PNG file makes Pillow’s Image.open() allocate and fill memory sized by the image dimensions the file claims, before Pillow’s built-in check for oversized images runs. A file claiming 22000×22000 pixels costs about 1.9 GB. Anyone who can get an application to open an image they supply, with default settings and no further calls such as load(), can cause a multi-gigabyte memory spike per file. If the claimed size exceeds the machine’s free memory, the operating system kills the process outright.
The bug is in PngImageFile._seek() in src/PIL/PngImagePlugin.py (around line 1000). For any APNG, _open() calls self._seek(0). When the first fcTL chunk requests OP_BACKGROUND disposal, _seek() calls Image.core.fill(self.mode, self.size) with the full IHDR size, which allocates and zero-fills width×height×4 bytes. OP_PREVIOUS takes the same path, because frame 0 rewrites it to OP_BACKGROUND. This all happens inside the plugin factory, so Image.open()’s _decompression_bomb_check(im.size) only runs after the memory has been touched. A 1×1 frame rectangle passes the only checks on the way.
Below available memory, the allocation is freed when DecompressionBombError propagates, so sustained pressure needs repeated or concurrent uploads. A 45000×45000 header gets the process killed by the out-of-memory killer on an 8 GB host. The attached reproducer opens two such files that differ in one byte (dispose_op 0 vs 1). Both end in DecompressionBombError, but peak resident memory is 17 MB for the first and 1864 MB for the second. The eager fill was introduced in 5e4e0fa6ee67 (“Use disposal settings from previous frame”, December 2020) and first shipped in 8.1.0. Two candidate patches with a regression test are attached.
References
Code Behaviors & Features
Detect and mitigate CVE-2026-112399 with GitLab Dependency Scanning
Secure your software supply chain by verifying that all open source dependencies used in your projects contain no disclosed vulnerabilities. Dependency Scanning using SBOM also detects vulnerabilities from proprietary advisories that this site does not include. Learn more about Dependency Scanning using SBOM →