Attack ChainAIDerived
Hypothetical attack flow derived from CVE metadata – not a confirmed exploit chain
-
AccessSubmit image with zero-entry palette
-
ExploitTrigger Image.quantize via attacker palette
-
ExecutionEmit uninitialized stack bytes as pixels
-
ImpactRecover addresses and canary from output
Vulnerability Assessment
| Weakness |
CWE
ASVS 5.0
V15 - Secure Coding and Architecture Variable initialization checks
|
| Exploitation Conditions | Exploitation requires that the target application call Pillow's Image.quantize(palette=p) with an attacker-controlled palette image whose palette has zero entries (p.palette.palette == b""), causing ImagingPaletteCacheUpdate() to leave its local cache array uninitialized and the topalette() conversion path to emit those bytes as output pixel indices in the returned PNG/GIF. Limiting factors: this is not Pillow's default or implicit behavior - the application must expose the quantize-with-palette code path to untrusted input, and the attacker must control the palette image specifically. Impact is confined to disclosure of uninitialized stack memory (addresses, stack-canary data) with no code execution, corruption, or crash. Affects Pillow 9.1.0 through versions before 13.0.0. |
| Impact | This is a medium-severity information-disclosure flaw (CVSS 4.0 base 6.9) rated CWE-457 (use of uninitialized variable). The CVSS 4.0 vector AV:N/AC:L/AT:N/PR:N/UI:N indicates network-reachable, low-complexity, unauthenticated triggering with no user interaction, but impact is confined to confidentiality at Low (VC:L; VI:N/VA:N) - a pure read of uninitialized stack memory with no corruption, out-of-bounds write, or crash. No EPSS score was provided, so exploitation probability cannot be quantified; the CVE is NOT in CISA KEV and no public exploit code was supplied, so exploitation status is 'no public exploit identified at time of analysis'. The source-code evidence (fix commit 13943c8) is a patch, not a weaponized PoC. The practical risk is tempered by a real precondition the raw vector obscures: the AV:N/PR:N scoring assumes the attacker can reach the vulnerable call path, but exploitation only occurs when an application invokes Image.quantize() with an attacker-controlled palette image that has zero entries - not Pillow's default behavior. Net assessment: a genuine but lower-tier priority - valuable as an ASLR/stack-canary-defeating leak primitive to chain with a separate memory-corruption bug rather than an independently critical issue. Patch to 13.0.0 where the quantize path is a realistic attack surface. |
| Exploit ScenarioDerived | A web application lets users upload an image and recolor it against a user-supplied palette via Pillow's Image.quantize(palette=...). An attacker uploads a palette image whose palette is empty (zero entries); Pillow's conversion path emits uninitialized stack bytes as pixel indices, and the attacker downloads the resulting PNG/GIF and reconstructs leaked stack contents such as pointers and stack-canary values. No public exploit code is known, but the low attack complexity (AC:L) makes reliable triggering straightforward once the palette path is reachable. |
Get an e-mail when this CVE is exploited, patched or re-scored. Free account.
Alert meAnalysisAIv1 – Oct 19, 2026
Uninitialized stack memory disclosure in Pillow 9.1.0 through 12.x allows an attacker who controls a palette image passed to Image.quantize(palette=p) to receive raw stack contents - including pointer addresses and stack-canary bytes - embedded as pixel indices in the returned PNG or GIF. Exploitation is not implicit in normal Pillow use: the application must expose the quantize-with-palette path to untrusted input and must accept an attacker-supplied palette whose palette data is empty (p.palette.palette == b""), which causes ImagingPaletteCacheUpdate() to leave its local cache array uninitialized before those bytes are emitted by the topalette() conversion path. The flaw yields confidentiality-only impact with no memory corruption or crash; no public exploit code or confirmed active exploitation (CISA KEV) was identified at time of analysis, and the vendor-released fix is Pillow 13.0.0.
RemediationAI
Vendor-released patch: upgrade to Pillow 13.0.0 or later (https://github.com/python-pillow/Pillow/releases/tag/13.0.0), which adds an explicit empty-palette rejection that raises ValueError("empty palette") from the topalette() conversion path and zero-initializes the palette cache array per commit 13943c8f857b22f073d30f0ef9b725a0d255f1a4; details are in GHSA-rfgq-q3w2-pmv2. Where an immediate upgrade is not possible, the practical compensating control is input validation in the calling application: before invoking Image.quantize(palette=p), inspect the supplied palette image and reject it when p.mode != "P" or p.palette is None or p.palette.palette == b"", returning an error to the user - this mirrors exactly the check the upstream patch performs and carries negligible side effects, since a zero-entry palette has no legitimate quantize semantics. A broader but more disruptive mitigation is to disable the quantize-with-palette feature entirely for untrusted input (for example by running image conversion in a subprocess that refuses palette-bearing requests), at the cost of losing a legitimate color-reduction capability; running the conversion in a short-lived worker process also limits the value of leaked stack data such as canary and address bytes, though it does not eliminate the disclosure itself. Because the defect discloses stack memory without crashing, it will not be caught by crash monitoring - inventory call sites of Image.quantize(palette=...) directly to confirm exposure.
Affected VersionsENISA
Affected Packages
Source: OSV (Open Source Vulnerabilities)
Affects your stack
Affects 1 package in pypi
Checking this CVE against your own stacks and servers is part of the Basic plan and up.
Technical ContextAI · show details
Pillow is the maintained fork of the Python Imaging Library, with its performance-critical imaging primitives implemented in C under src/libImaging and exposed to Python through the _imaging extension module. This issue is CWE-457 (use of uninitialized variable): in ImagingPaletteCacheUpdate() (src/libImaging/Palette.c) the local cache array is populated by looping over the palette's entries, so a palette with zero entries leaves the array contents undefined on the stack, and the subsequent topalette() conversion in Convert.c copies those undefined values out as output pixel indices. The result is an information leak of stack memory without any out-of-bounds access, memory corruption, or crash - the conversion simply succeeds and returns an image whose index channel is derived from uninitialized stack bytes. The trigger is the quantize()-with-palette path, where the caller passes a mode "P" image as the reference palette; the committed upstream fix (13943c8f857b22f073d30f0ef9b725a0d255f1a4) adds an explicit palette->size == 0 check that raises ImagingError_ValueError("empty palette") from topalette() and also zero-initializes the cache entry in ImagingPaletteCacheUpdate(), plus a regression test asserting that quantize(palette=p) raises ValueError for an empty palette. Note that some feed metadata tags this as a "Buffer Overflow"; the authoritative root-cause class is uninitialized memory use, and the assessed CVSS v3.1 vector (AV:N/AC:L/PR:N/UI:N/S:U/C:L/I:N/A:N) confirms a remote, unauthenticated, low-confidentiality-only impact with no integrity or availability effect.
Know when Pillow gets its next vulnerability
- Watch products and get an email when something new is published
- Check this CVE against your own stack and servers
- Exploit and PoC references, threat intelligence from 22 sources
No credit card · 7-day full trial
Severity by source
CVSS:4.0/AV:N/AC:L/AT:N/PR:N/UI:N/VC:L/VI:N/VA:N/SC:N/SI:N/SA:N
Attacker-supplied palette image can arrive over the network with no auth or interaction (AV:N/PR:N/UI:N), triggering reliably (AC:L); only a partial stack-memory read results, so C:L and I:N/A:N.
Primary rating from Vendor (GitHub_M).
CVSS VectorVendor: GitHub_M
Lifecycle Timeline
2DescriptionCVE.org
Pillow is a Python imaging library. From 9.1.0 until 13.0.0, Pillow can disclose uninitialized stack memory when Image.quantize() uses an empty palette. ImagingPaletteCacheUpdate() leaves a local cache array uninitialized when the palette has zero entries, and the conversion path emits those bytes as output pixel indices. An attacker who controls the palette image can obtain stack contents from a returned PNG or GIF. This can disclose addresses and stack-canary data without an out-of-bounds access, memory corruption, or process crash. This issue is fixed in version 13.0.0.
Blast Radius
ecosystem impact- 62 pypi packages depend on pillow (58 direct, 4 indirect)
Ecosystem-wide dependent count for version 9.1.0.
Threat Intelligence Overview
How this decision was reached
The engine reads each signal below and applies a fixed list of rules from top to bottom. The first rule that matches sets the recommended action – like a statement, every line is shown.
What every action level means
SSVC AssessmentENISA
Priority Score
libImaging/TgaRleDecode.c in Pillow 9.1.0 has a heap buffer overflow in the processing of invalid TGA image files. Rated
Denial of service in Python Pillow (versions 8.2.0 through 12.2.0) allows remote attackers to exhaust memory during JPEG
Out-of-bounds memory disclosure in Python Pillow before 12.3.0 lets an attacker who supplies a crafted McIdas AREA image
Heap out-of-bounds write in Python Pillow prior to 12.3.0 lets an attacker who controls the rank-filter size parameter c
Uncontrolled memory consumption in Python Pillow (PIL) versions 5.1.0 through 12.2.x allows a remote attacker to cause d
The package pillow 5.2.0 and before 8.3.2 are vulnerable to Regular Expression Denial of Service (ReDoS) via the getrgb
Pillow is a Python imaging library. In versions 11.2.0 to before 11.3.0, there is a heap buffer overflow when writing a
Integer overflow in the ImagingResampleHorizontal function in libImaging/Resample.c in Pillow before 3.1.1 allows remote
Python Image Library (PIL) 1.1.7 and earlier and Pillow 2.3 might allow remote attackers to execute arbitrary commands v
Pillow versions 11.0.0 through 12.x (fixed in 13.0.0) can reuse a stale native ImagingCore buffer when a multi-frame ima
Pillow through 8.2.0 and PIL (aka Python Imaging Library) through 1.1.7 allow an attacker to pass controlled parameters
An issue was discovered in Pillow before 8.1.1. Rated critical severity (CVSS 9.8), this vulnerability is remotely explo
EUVD-2026-104660
GHSA-rfgq-q3w2-pmv2
NVD
CVE.org
EPSS
Exploit-DB