CVE-2026-96778
Pillow: Heap buffer overflow writing JPEG comment after ICC profile fills buffer
Pillow is a Python imaging library. From 9.4.0 until 13.0.0, ImagingJpegEncode() in src/libImaging/JpegEncode.c can call jpeg_write_marker() for a JPEG COM comment when an ICC profile has exactly filled the 65536-byte encoder buffer. libjpeg writes one byte before checking the exhausted free_in_buffer counter, which then wraps and permits the attacker-controlled comment and subsequent compressed image data to overwrite adjacent heap memory. Re-saving an untrusted image as JPEG while preserving its ICC profile and forwarded comment can crash the process and may enable code execution in suitable runtime and heap layouts. This issue is fixed in version 13.0.0.
Attack profile
How easy it is to exploit
- Attack vector
- Network
- Complexity
- Low
- Privileges needed
- None
- User interaction
- Passive
What an attacker can affect
- Confidentiality
- High
- Integrity
- High
- Availability
- High
Exploit likelihood
What each source reports
CVE List Score used
7.7
Pillow: Heap buffer overflow writing JPEG comment after ICC profile fills buffer
Pillow is a Python imaging library. From 9.4.0 until 13.0.0, ImagingJpegEncode() in src/libImaging/JpegEncode.c can call jpeg_write_marker() for a JPEG COM comment when an ICC profile has exactly filled the 65536-byte encoder buffer. libjpeg writes one byte before checking the exhausted free_in_buffer counter, which then wraps and permits the attacker-controlled comment and subsequent compressed image data to overwrite adjacent heap memory. Re-saving an untrusted image as JPEG while preserving its ICC profile and forwarded comment can crash the process and may enable code execution in suitable runtime and heap layouts. This issue is fixed in version 13.0.0.
- Record
CVE-2026-96778- CVSS 4.0
- 7.7 High
CVSS:4.0/AV:N/AC:L/AT:P/PR:N/UI:P/VC:H/VI:H/VA:H/SC:N/SI:N/SA:N - Weakness
- CWE-787
- Updated
- 2026-11-02
EUVDEUVD-2026-107566
7.7
Pillow is a Python imaging library. From 9.4.0 until 13.0.0, ImagingJpegEncode() in src/libImaging/JpegEncode.c can call jpeg_write_marker() for a JPEG COM comment when an ICC profile has exactly filled the 65536-byte encoder buffer. libjpeg writes one byte before checking the exhausted free_in_buffer counter, which then wraps and permits the attacker-controlled comment and subsequent compressed image data to overwrite adjacent heap memory. Re-saving an untrusted image as JPEG while preserving its ICC profile and forwarded comment can crash the process and may enable code execution in suitable runtime and heap layouts. This issue is fixed in version 13.0.0.
- Record
EUVD-2026-107566- CVSS 4.0
- 7.7 High
CVSS:4.0/AV:N/AC:L/AT:P/PR:N/UI:P/VC:H/VI:H/VA:H/SC:N/SI:N/SA:N - Updated
- 2026-11-02
GitHub AdvisoriesGHSA-g7cr-3p24-7wf7
7.7
Pillow: Heap buffer overflow writing JPEG comment after ICC profile fills buffer
============================================================================
Heap buffer overflow writing JPEG comment after ICC profile fills buffer
Location: src/libImaging/JpegEncode.c:330 in ImagingJpegEncode()
Commit: a707c6b21c313880d0771e54965d142dd42358b6
============================================================================
A heap buffer overflow in Pillow's JPEG encoder lets anyone who can supply an image write up to 64 KB of bytes they choose, followed by the rest of the compressed image, past the end of a 64 KB heap buffer. The target is any application that re-saves the image as JPEG while keeping its colour profile. The reliable result is that the Python process is killed outright rather than raising an exception. Because the overwritten memory sits directly in front of function pointers that the encoder calls next, this could allow code execution, though the attached reproducer demonstrates only the crash.
The bug is in ImagingJpegEncode() in src/libImaging/JpegEncode.c. State 4 (line 330) calls jpeg_write_marker() for the COM comment marker without checking that the output buffer has room. Meanwhile, JpegImagePlugin._save() sizes that buffer from the EXIF and ICC/XMP data only and reserves nothing for the comment. When a 65498-byte ICC profile fills the 65536-byte buffer exactly, libjpeg's emit_byte() stores one byte past the end and then decrements free_in_buffer from 0. The size_t counter wraps, so the marker, the comment and the entire compressed image are written out of bounds.
Triggering it takes only a valid JPEG (or PNG) carrying that profile and any comment, passed through Image.open() and then im.save(..., "JPEG", icc_profile=im.info.get("icc_profile")). That is the documented way to preserve colour. The comment is forwarded from im.info automatically, and no non-default setting is involved.
The attached reproducer re-saves such a file on the stock build, and the process dies with SIGSEGV. An identical file without the comment saves normally. An ASan build of Pillow will not flag this, because the stray writes happen inside the system libjpeg-turbo. Valgrind does report it, as an invalid write immediately after the 65569-byte allocation.
The unguarded call was introduced in e50ae85ea406 ("Use jpeg_write_marker to write comment", 2022-12-05) and first shipped in 9.4.0.
Details
ImagingJpegEncode() (src/libImaging/JpegEncode.c) is a resumable state machine that fills a caller-supplied output buffer of bytes bytes and returns when it is full. State 4 writes the JPEG COM marker with jpeg_write_marker() without first checking that the buffer has any room left. When the preceding state 3 — the verbatim copy of the "extra" APP segments (ICC profile / XMP) — ends exactly at the last byte of the buffer, jpeg_write_marker() is entered with free_in_buffer == 0. libjpeg's emit_byte() stores the byte first and tests --free_in_buffer == 0 afterwards, so the size_t counter wraps to 2^64-1 instead of triggering the "buffer full" path, and the 4-byte marker header, the whole comment, and then (state 5) the DQT/SOF/DHT/SOS headers and the entire entropy-coded image are written linearly past the end of the 65536-byte heap buffer allocated in src/encode.c.
A JPEG laid out as
FFD8 SOI
FFE2 <len> "ICC_PROFILE\0" 01 01 <65498 bytes> -> im.info["icc_profile"]
FFFE <len> <comment, any length 1..65533> -> im.info["comment"]
<any baseline RGB JPEG body>
opened with Image.open() and re-saved with the usual colour-profile-preserving call
im.save(out, "JPEG", icc_profile=im.info.get("icc_profile"))
kills the Python process on the stock build at this commit: glibc aborts with realloc(): invalid next size / corrupted size vs. prev_size, or the process takes SIGSEGV inside jpeg_write_marker/jpeg_write_scanlines. Stopping at JpegEncode.c:330 in gdb shows `next_output_byte - buf ==…
- Record
GHSA-g7cr-3p24-7wf7- CVSS 4.0
- 7.7 High
CVSS:4.0/AV:N/AC:L/AT:P/PR:N/UI:P/VC:H/VI:H/VA:H/SC:N/SI:N/SA:N - Weakness
- CWE-787
- Updated
- 2026-11-02
NVD
7.7
Pillow is a Python imaging library. From 9.4.0 until 13.0.0, ImagingJpegEncode() in src/libImaging/JpegEncode.c can call jpeg_write_marker() for a JPEG COM comment when an ICC profile has exactly filled the 65536-byte encoder buffer. libjpeg writes one byte before checking the exhausted free_in_buffer counter, which then wraps and permits the attacker-controlled comment and subsequent compressed image data to overwrite adjacent heap memory. Re-saving an untrusted image as JPEG while preserving its ICC profile and forwarded comment can crash the process and may enable code execution in suitable runtime and heap layouts. This issue is fixed in version 13.0.0.
- Record
CVE-2026-96778- CVSS 4.0
- 7.7 High
CVSS:4.0/AV:N/AC:L/AT:P/PR:N/UI:P/VC:H/VI:H/VA:H/SC:N/SI:N/SA:N/E:X/CR:X/IR:X/AR:X/MAV:X/MAC:X/MAT:X/MPR:X/MUI:X/MVC:X/MVI:X/MVA:X/MSC:X/MSI:X/MSA:X/S:X/AU:X/R:X/V:X/RE:X/U:X - CVSS 3.1
- 8.8 High
CVSS:3.1/AV:N/AC:L/PR:N/UI:R/S:U/C:H/I:H/A:H - Weakness
- CWE-787
- Updated
- 2026-11-02
OSV
7.7
Pillow: Heap buffer overflow writing JPEG comment after ICC profile fills buffer
Pillow is a Python imaging library. From 9.4.0 until 13.0.0, ImagingJpegEncode() in src/libImaging/JpegEncode.c can call jpeg_write_marker() for a JPEG COM comment when an ICC profile has exactly filled the 65536-byte encoder buffer. libjpeg writes one byte before checking the exhausted free_in_buffer counter, which then wraps and permits the attacker-controlled comment and subsequent compressed image data to overwrite adjacent heap memory. Re-saving an untrusted image as JPEG while preserving its ICC profile and forwarded comment can crash the process and may enable code execution in suitable runtime and heap layouts. This issue is fixed in version 13.0.0.
- Record
CVE-2026-96778- CVSS 4.0
- 7.7 High
CVSS:4.0/AV:N/AC:L/AT:P/PR:N/UI:P/VC:H/VI:H/VA:H/SC:N/SI:N/SA:N - Weakness
- CWE-787
- Updated
- 2026-11-02
OSVDEBIAN-CVE-2026-96778
8.8
Pillow is a Python imaging library. From 9.4.0 until 13.0.0, ImagingJpegEncode() in src/libImaging/JpegEncode.c can call jpeg_write_marker() for a JPEG COM comment when an ICC profile has exactly filled the 65536-byte encoder buffer. libjpeg writes one byte before checking the exhausted free_in_buffer counter, which then wraps and permits the attacker-controlled comment and subsequent compressed image data to overwrite adjacent heap memory. Re-saving an untrusted image as JPEG while preserving its ICC profile and forwarded comment can crash the process and may enable code execution in suitable runtime and heap layouts. This issue is fixed in version 13.0.0.
- Record
DEBIAN-CVE-2026-96778- CVSS 3.1
- 8.8 High
CVSS:3.1/AV:N/AC:L/PR:N/UI:R/S:U/C:H/I:H/A:H - Updated
- 2026-11-02
Show 10 moreShow less
OSVGHSA-g7cr-3p24-7wf7
7.7
Pillow: Heap buffer overflow writing JPEG comment after ICC profile fills buffer
============================================================================
Heap buffer overflow writing JPEG comment after ICC profile fills buffer
Location: src/libImaging/JpegEncode.c:330 in ImagingJpegEncode()
Commit: a707c6b21c313880d0771e54965d142dd42358b6
============================================================================
A heap buffer overflow in Pillow's JPEG encoder lets anyone who can supply an image write up to 64 KB of bytes they choose, followed by the rest of the compressed image, past the end of a 64 KB heap buffer. The target is any application that re-saves the image as JPEG while keeping its colour profile. The reliable result is that the Python process is killed outright rather than raising an exception. Because the overwritten memory sits directly in front of function pointers that the encoder calls next, this could allow code execution, though the attached reproducer demonstrates only the crash.
The bug is in ImagingJpegEncode() in src/libImaging/JpegEncode.c. State 4 (line 330) calls jpeg_write_marker() for the COM comment marker without checking that the output buffer has room. Meanwhile, JpegImagePlugin._save() sizes that buffer from the EXIF and ICC/XMP data only and reserves nothing for the comment. When a 65498-byte ICC profile fills the 65536-byte buffer exactly, libjpeg's emit_byte() stores one byte past the end and then decrements free_in_buffer from 0. The size_t counter wraps, so the marker, the comment and the entire compressed image are written out of bounds.
Triggering it takes only a valid JPEG (or PNG) carrying that profile and any comment, passed through Image.open() and then im.save(..., "JPEG", icc_profile=im.info.get("icc_profile")). That is the documented way to preserve colour. The comment is forwarded from im.info automatically, and no non-default setting is involved.
The attached reproducer re-saves such a file on the stock build, and the process dies with SIGSEGV. An identical file without the comment saves normally. An ASan build of Pillow will not flag this, because the stray writes happen inside the system libjpeg-turbo. Valgrind does report it, as an invalid write immediately after the 65569-byte allocation.
The unguarded call was introduced in e50ae85ea406 ("Use jpeg_write_marker to write comment", 2022-12-05) and first shipped in 9.4.0.
Details
ImagingJpegEncode() (src/libImaging/JpegEncode.c) is a resumable state machine that fills a caller-supplied output buffer of bytes bytes and returns when it is full. State 4 writes the JPEG COM marker with jpeg_write_marker() without first checking that the buffer has any room left. When the preceding state 3 — the verbatim copy of the "extra" APP segments (ICC profile / XMP) — ends exactly at the last byte of the buffer, jpeg_write_marker() is entered with free_in_buffer == 0. libjpeg's emit_byte() stores the byte first and tests --free_in_buffer == 0 afterwards, so the size_t counter wraps to 2^64-1 instead of triggering the "buffer full" path, and the 4-byte marker header, the whole comment, and then (state 5) the DQT/SOF/DHT/SOS headers and the entire entropy-coded image are written linearly past the end of the 65536-byte heap buffer allocated in src/encode.c.
A JPEG laid out as
FFD8 SOI
FFE2 <len> "ICC_PROFILE\0" 01 01 <65498 bytes> -> im.info["icc_profile"]
FFFE <len> <comment, any length 1..65533> -> im.info["comment"]
<any baseline RGB JPEG body>
opened with Image.open() and re-saved with the usual colour-profile-preserving call
im.save(out, "JPEG", icc_profile=im.info.get("icc_profile"))
kills the Python process on the stock build at this commit: glibc aborts with realloc(): invalid next size / corrupted size vs. prev_size, or the process takes SIGSEGV inside jpeg_write_marker/jpeg_write_scanlines. Stopping at JpegEncode.c:330 in gdb shows `next_output_byte - buf ==…
- Record
GHSA-g7cr-3p24-7wf7- CVSS 4.0
- 7.7 High
CVSS:4.0/AV:N/AC:L/AT:P/PR:N/UI:P/VC:H/VI:H/VA:H/SC:N/SI:N/SA:N - Weakness
- CWE-787
- Updated
- 2026-11-02
OSVUBUNTU-CVE-2026-96778
7.7
Pillow is a Python imaging library. From 9.4.0 until 13.0.0, ImagingJpegEncode() in src/libImaging/JpegEncode.c can call jpeg_write_marker() for a JPEG COM comment when an ICC profile has exactly filled the 65536-byte encoder buffer. libjpeg writes one byte before checking the exhausted free_in_buffer counter, which then wraps and permits the attacker-controlled comment and subsequent compressed image data to overwrite adjacent heap memory. Re-saving an untrusted image as JPEG while preserving its ICC profile and forwarded comment can crash the process and may enable code execution in suitable runtime and heap layouts. This issue is fixed in version 13.0.0.
- Record
UBUNTU-CVE-2026-96778- CVSS 4.0
- 7.7 High
CVSS:4.0/AV:N/AC:L/AT:P/PR:N/UI:P/VC:H/VI:H/VA:H/SC:N/SI:N/SA:N - CVSS 3.1
- 8.8 High
CVSS:3.1/AV:N/AC:L/PR:N/UI:R/S:U/C:H/I:H/A:H - Updated
- 2026-11-04
OSVBIT-pillow-2026-96778 No score
Pillow: Heap buffer overflow writing JPEG comment after ICC profile fills buffer
Pillow is a Python imaging library. From 9.4.0 until 13.0.0, ImagingJpegEncode() in src/libImaging/JpegEncode.c can call jpeg_write_marker() for a JPEG COM comment when an ICC profile has exactly filled the 65536-byte encoder buffer. libjpeg writes one byte before checking the exhausted free_in_buffer counter, which then wraps and permits the attacker-controlled comment and subsequent compressed image data to overwrite adjacent heap memory. Re-saving an untrusted image as JPEG while preserving its ICC profile and forwarded comment can crash the process and may enable code execution in suitable runtime and heap layouts. This issue is fixed in version 13.0.0.
- Record
BIT-pillow-2026-96778- Updated
- 2026-11-02
OSVCLSA-2026-1792743656 No score
TuxCare security update for pillow (6 CVEs)
TuxCare rebuilt pillow to address 6 CVEs. Fixed in 11.3.0.post9+tuxcare.
- Record
CLSA-2026-1792743656- Updated
- 2026-11-02
OSVCLSA-2026-1792752131 No score
TuxCare security update for pillow (6 CVEs)
TuxCare rebuilt pillow to address 6 CVEs. Fixed in 11.2.1.post11+tuxcare.
- Record
CLSA-2026-1792752131- Updated
- 2026-11-02
OSVCLSA-2026-1793013873 No score
TuxCare security update for pillow (3 CVEs)
TuxCare rebuilt pillow to address 3 CVEs. Fixed in 10.4.0.post14+tuxcare.
- Record
CLSA-2026-1793013873- Updated
- 2026-11-02
OSVCLSA-2026-1793017906 No score
TuxCare security update for pillow (3 CVEs)
TuxCare rebuilt pillow to address 3 CVEs. Fixed in 9.5.0.post12+tuxcare.
- Record
CLSA-2026-1793017906- Updated
- 2026-11-02
OSVCLSA-2026-1793101376 No score
TuxCare security update for pillow (1 CVE)
TuxCare rebuilt pillow to address 1 CVE. Fixed in 9.4.0.post14+tuxcare.
- Record
CLSA-2026-1793101376- Updated
- 2026-11-02
OSVopenSUSE-SU-2026:12251-1 No score
python313-Pillow-13.0.0-2.1 on GA media
These are all security issues fixed in the python313-Pillow-13.0.0-2.1 package on the GA media of openSUSE Tumbleweed.
- Record
openSUSE-SU-2026:12251-1- Updated
- 2026-11-02
OSVROOT-APP-PYPI-CVE-2026-96778 No score
CVE-2026-96778 in pillow - Patched by Root
Root has patched CVE-2026-96778 in the pillow package for Root:PyPI. Multiple fixed versions available.
- Record
ROOT-APP-PYPI-CVE-2026-96778- Updated
- 2026-11-06
Affected products
Affected packages
| Package | Affected | Fixed |
|---|---|---|
pillowPyPI |
9.4.0 up to 13.0.0 | 13.0.0 |
pillowBitnami |
9.4.0 up to 13.0.0 | 13.0.0 |
pillowTuxCare:PyPI From an advisory covering 6 CVEs |
11.3.0 up to 11.3.0.post9+tuxcare, plus listed versions 11.3.0.post1+tuxcare11.3.0.post2+tuxcare11.3.0.post3+tuxcare11.3.0.post4+tuxcare11.3.0.post5+tuxcare11.3.0.post6+tuxcare11.3.0.post7+tuxcare11.3.0.post8+tuxcare |
11.3.0.post9+tuxcare |
pillowTuxCare:PyPI From an advisory covering 6 CVEs |
11.2.1 up to 11.2.1.post11+tuxcare, plus listed versions 11.2.1.post1+tuxcare11.2.1.post10+tuxcare11.2.1.post2+tuxcare11.2.1.post3+tuxcare11.2.1.post4+tuxcare Show 5 moreShow less11.2.1.post5+tuxcare11.2.1.post6+tuxcare11.2.1.post7+tuxcare11.2.1.post8+tuxcare11.2.1.post9+tuxcare |
11.2.1.post11+tuxcare |
pillowTuxCare:PyPI From an advisory covering 3 CVEs |
10.4.0 up to 10.4.0.post14+tuxcare, plus listed versions 10.4.0.post1+tuxcare10.4.0.post10+tuxcare10.4.0.post11+tuxcare10.4.0.post12+tuxcare10.4.0.post13+tuxcare Show 8 moreShow less10.4.0.post2+tuxcare10.4.0.post3+tuxcare10.4.0.post4+tuxcare10.4.0.post5+tuxcare10.4.0.post6+tuxcare10.4.0.post7+tuxcare10.4.0.post8+tuxcare10.4.0.post9+tuxcare |
10.4.0.post14+tuxcare |
pillowTuxCare:PyPI From an advisory covering 3 CVEs |
9.5.0 up to 9.5.0.post12+tuxcare, plus listed versions 9.5.0.post1+tuxcare9.5.0.post10+tuxcare9.5.0.post11+tuxcare9.5.0.post2+tuxcare9.5.0.post3+tuxcare Show 6 moreShow less9.5.0.post4+tuxcare9.5.0.post5+tuxcare9.5.0.post6+tuxcare9.5.0.post7+tuxcare9.5.0.post8+tuxcare9.5.0.post9+tuxcare |
9.5.0.post12+tuxcare |
pillowTuxCare:PyPI |
9.4.0 up to 9.4.0.post14+tuxcare, plus listed versions 9.4.0.post1+tuxcare9.4.0.post10+tuxcare9.4.0.post11+tuxcare9.4.0.post12+tuxcare9.4.0.post13+tuxcare Show 8 moreShow less9.4.0.post2+tuxcare9.4.0.post3+tuxcare9.4.0.post4+tuxcare9.4.0.post5+tuxcare9.4.0.post6+tuxcare9.4.0.post7+tuxcare9.4.0.post8+tuxcare9.4.0.post9+tuxcare |
9.4.0.post14+tuxcare |
pillowDebian:12 |
All versions, plus listed versions 10.0.0-110.1.0-110.2.0-110.3.0-110.3.0-2 Show 19 moreShow less10.4.0-110.4.0-1.111.1.0-111.1.0-211.1.0-311.1.0-411.1.0-511.2.1-111.3.0-112.0.0-112.1.0-112.1.1-112.1.1-212.2.0-112.3.0-113.0.0-19.4.0-1.19.4.0-1.1+deb12u19.5.0-1 |
None known |
pillowDebian:13 |
All versions, plus listed versions 11.1.0-511.1.0-5+deb13u111.1.0-5+deb13u211.1.0-5+deb13u311.1.0-5+deb13u4 Show 9 moreShow less11.2.1-111.3.0-112.0.0-112.1.0-112.1.1-112.1.1-212.2.0-112.3.0-113.0.0-1 |
None known |
pillowDebian:14 |
All versions, plus listed versions 11.1.0-511.2.1-111.3.0-112.0.0-112.1.0-1 Show 5 moreShow less12.1.1-112.1.1-212.2.0-112.3.0-113.0.0-1 |
None known |
Show 7 moreShow less
| Package | Affected | Fixed |
|---|---|---|
pillowPyPI |
9.4.0 up to 13.0.0, plus listed versions 10.0.010.0.110.1.010.2.010.3.0 Show 11 moreShow less10.4.011.0.011.1.011.2.111.3.012.0.012.1.012.1.112.2.012.3.09.5.0 |
13.0.0 |
pillowRoot:PyPI |
before 10.4.0+aikido.16 | 10.4.0+aikido.1612.3.0+aikido.310.3.0+aikido.1912.3.0+aikido.410.4.0+aikido.1710.3.0+aikido.209.4.0+aikido.111.0.0+aikido.1412.2.0+aikido.99.5.0+aikido.1910.4.0+aikido.18 |
pillow-python2Ubuntu:Pro:20.04:LTS |
All versions, plus listed versions 6.2.1-3~build16.2.1-36.2.1-3ubuntu0.1~esm16.2.1-3ubuntu0.1~esm2 |
None known |
pillowUbuntu:24.04:LTS |
All versions, plus listed versions 10.0.0-110.1.0-110.2.0-110.2.0-1build110.2.0-1ubuntu110.2.0-1ubuntu1.210.2.0-1ubuntu1.310.2.0-1ubuntu1.4 |
None known |
pillowUbuntu:26.10 |
All versions, plus listed versions 12.1.1-2ubuntu112.3.0-1ubuntu1 |
None known |
pillowUbuntu:26.04:LTS |
All versions, plus listed versions 11.3.0-1ubuntu111.3.0-1ubuntu212.0.0-1ubuntu112.1.1-1ubuntu112.1.1-2ubuntu1 Show 4 moreShow less12.1.1-2ubuntu1.112.1.1-2ubuntu1.212.1.1-2ubuntu1.312.1.1-2ubuntu1.4 |
None known |
python-PillowopenSUSE:Tumbleweed From an advisory covering 6 CVEs |
before 13.0.0-2.1 | 13.0.0-2.1 |
Public exploits
Links only. Every CVE stores no exploit code.
| Source | Link | Date |
|---|---|---|
| PoC in GitHub | paktiko1986/CVE-2026-96778-pillow | 2026-10-28 |
History
| Recorded | Changed | Sources |
|---|---|---|
| affected | OSV | |
| affected | ||
| affected | OSV | |
| affected | OSV | |
| affected | OSV | |
| affected | OSV | |
| affected, facts | OSV | |
| affected | OSV | |
| first indexed | CVE List, EUVD, GitHub Advisories, NVD, OSV, PoC in GitHub |
Dates are when Every CVE recorded each change. Upstream dates may differ.
In short
CVE-2026-96778 is a high vulnerability (CVSS 7.7) in Python Pillow, published October 21, 2026. Public exploit code exists. EPSS puts the chance of exploitation in the next 30 days at 0.45%, the 39th percentile. Fixed in pillow 13.0.0.
References
github.com/python-pillow/Pillow/security/advisories/GHSA-g7cr-3p24-7wf7
github.com/python-pillow/Pillow/pull/10124
github.com/python-pillow/Pillow/commit/02561b8dc6117d5670d4b469fecdd02c70854f9b
github.com/python-pillow/Pillow/releases/tag/13.0.0
nvd.nist.gov/vuln/detail/CVE-2026-96778
github.com/advisories/GHSA-g7cr-3p24-7wf7
Show 11 moreShow less
github.com/CVEProject/cvelistV5/tree/main/cves/2026/96xxx/CVE-2026-96778.json
security-tracker.debian.org/tracker/CVE-2026-96778
github.com/python-pillow/Pillow
ubuntu.com/security/CVE-2026-96778
cve.org/CVERecord?id=CVE-2026-96778
suse.com/security/cve/CVE-2026-112902
suse.com/security/cve/CVE-2026-96636
suse.com/security/cve/CVE-2026-96638
suse.com/security/cve/CVE-2026-96640
suse.com/security/cve/CVE-2026-96642
suse.com/security/cve/CVE-2026-96778
Left out here: the rest of 2 source descriptions. The JSON record has them.