CVE-2026-112396

highpriority · track · 30EPSS 0.007 · 53 %ileUS
grimoire priorityP2 · Scheduled
Exploitable?
—
no known exploitation
Likely / severe?
0.69% (53rd) EPSS
CVSS 7.5 · high
Is it mine?
3 products
Check your exposure
Who says so?
2 sources
osv · nvd

EPSS · scored 2026-10-27

Pillow is a Python imaging library. From 11.3.0 until 13.0.0, Pillow has a heap use-after-free when libtiff rejects a tag while encoding TIFF data to an in-memory buffer. When an application saves attacker-influenced TIFF tags to BytesIO, libtiff can reject a tag during encoding in ImagingLibTiffEncode; the error path then frees the output buffer without closing or clearing the TIFF handle, and later cleanup flushes through the write callback into freed memory, which can crash the process and may enable code execution. This issue is fixed in version 13.0.0.

01

cvss

Technical severity, 0–10. One row per scoring source.

7.5
010

base score 0–10 · higher = more severe · hover a vector to decode⚠ sources disagree · medium–high · 5.9–7.5

v3.17.5highCVSS:3.1/AV:N/AC:L/PR:N/UI:N/S:U/C:N/I:N/A:Hprimary · NVD / NIST USexploitability 3.9 · impact 3.6
v3.15.9mediumCVSS:3.1/AV:N/AC:H/PR:N/UI:N/S:U/C:N/I:N/A:Hsecondary · security-advisories@github.comexploitability 2.2 · impact 3.6
v3.15.9mediumCVSS:3.1/AV:N/AC:H/PR:N/UI:N/S:U/C:N/I:N/A:Hsecondary · OSV
v3.16.9mediumCVSS:3.1/AV:N/AC:L/PR:N/UI:N/S:U/C:N/I:N/A:H/E:Usecondary · CVSS-BT (t0sche)
02

ssvc

A stakeholder decision — act, attend, or track — from exploitation and impact.

Trackcoordinatorcisa_ssvcUS
03

weaknesses

The CWE weakness classes this flaw belongs to.

04

affected products (3)

Products and version ranges known to be affected.

05

advisories (3)

Vendor and ecosystem advisories describing this.

  • GHSA-4rr5-89j8-mwwmPillow: Heap use-after-free when encoding TIFF to an in-memory buffer2026-10-21ghsa · osvUS

    ### Summary Saving an image as TIFF to an in-memory buffer can trigger a heap use-after-free if libtiff rejects a tag at encode time. When `TIFFWriteScanline` fails, the encoder frees its output buffer but leaves the libtiff handle open. Later, when the encoder object is torn down, `TIFFClose` flushes buffered bytes through the write callback and writes into the freed buffer. An application that re-encodes attacker-influenced images to TIFF in memory can be crashed and is a candidate for remote code execution. ### Details The failure path in `ImagingLibTiffEncode` frees `clientstate->data` for the in-memory case but does not close the TIFF or null `clientstate->tiff` (the file-descriptor branch just above it does set `tiff = NULL`): - `src/libImaging/TiffDecode.c:1041-1046` Teardown then calls `ImagingLibTiffEncodeCleanup`, which runs `TIFFClose(tiff)` because `tiff` is still set: - `src/encode.c:99-101` - `src/libImaging/TiffDecode.c:955` `TIFFClose` flushes through `_tiffWriteProc`, which reallocs and memcpys into the freed `state->data`: - `src/libImaging/TiffDecode.c:103-115` The Predictor tag is a convenient trigger: the floating-point predictor (value 3) is invalid for integer sample data, so libtiff aborts the write. ### PoC ```python import io from PIL import Image # In-memory TIFF re-encode. libtiff rejects Predictor=3 (floating point) on integer # data, so TIFFWriteScanline fails. The encoder frees clientstate->data but leaves the # TIFF open; cleanup's TIFFClose then writes through the callback into the freed buffer. im = Image.new("L", (64, 64)) buf = io.BytesIO() im.save(buf, format="TIFF", compression="tiff_lzw", tiffinfo={317: 3}) # 317 = Predictor ``` Run it: ``` $ python 01_poc.py PredictorSetup: Floating point "Predictor" not supported with 1 data format. OSError: encoder error -2 when writing image file Segmentation fault (core dumped) ``` Observed on a source build of commit `3e2ab96` with libtiff. The process aborts during cleanup after the encoder error. Depending on heap state the same run sometimes reports `corrupted double-linked list` instead of a segfault; both are the same write into freed memory. Under AddressSanitizer (build with `-fsanitize=address`), relevant frames: ``` ==ERROR: AddressSanitizer: heap-use-after-free on address 0x7ef737b48804 WRITE of size 4 at 0x7ef737b48804 thread T0 #1 _tiffWriteProc src/libImaging/TiffDecode.c:115 #3 TIFFFlush libtiff.so.6 #5 TIFFClose libtiff.so.6 #6 ImagingLibTiffEncodeCleanup src/libImaging/TiffDecode.c:955 #7 _dealloc src/encode.c:100 freed by thread T0 here: #1 ImagingLibTiffEncode src/libImaging/TiffDecode.c:1045 #2 _encode src/encode.c:139 previously allocated by thread T0 here: #1 ImagingLibTiffEncodeInit src/libImaging/TiffDecode.c:863 #2 PyImaging_LibTiffEncoderNew src/encode.c:757 SUMMARY: AddressSanitizer: heap-use-after-free src/libImaging/TiffDecode.c:115 in _tiffWriteProc ``` The buffer allocated in `ImagingLibTiffEncodeInit` is freed in `ImagingLibTiffEncode`, then written by `_tiffWriteProc` during the `TIFFClose` flush that runs from the encoder's `_dealloc`. ### Impact Use-after-free in a C extension. Affects any service that converts or thumbnails untrusted images to TIFF in memory (a `BytesIO` or other non-seekable target). Result is a crash and possible memory corruption leading to code execution.

  • BIT-pillow-2026-112396Pillow: Heap use-after-free when encoding TIFF to an in-memory buffer2026-10-26vendor · osvUS

    Pillow is a Python imaging library. From 11.3.0 until 13.0.0, Pillow has a heap use-after-free when libtiff rejects a tag while encoding TIFF data to an in-memory buffer. When an application saves attacker-influenced TIFF tags to BytesIO, libtiff can reject a tag during encoding in ImagingLibTiffEncode; the error path then frees the output buffer without closing or clearing the TIFF handle, and later cleanup flushes through the write callback into freed memory, which can crash the process and may enable code execution. This issue is fixed in version 13.0.0.

  • PYSEC-2026-43282026-10-19vendor · osvUS

    Pillow is a Python imaging library. From 11.3.0 until 13.0.0, Pillow has a heap use-after-free when libtiff rejects a tag while encoding TIFF data to an in-memory buffer. When an application saves attacker-influenced TIFF tags to BytesIO, libtiff can reject a tag during encoding in ImagingLibTiffEncode; the error path then frees the output buffer without closing or clearing the TIFF handle, and later cleanup flushes through the write callback into freed memory, which can crash the process and may enable code execution. This issue is fixed in version 13.0.0.

06

also known as (3)

Other names and identifiers for this entity.

07

sources

Which sources assert this record, and when.

published 2026-10-19modified 2026-10-26
08

references (3) nvd

External citations — patches, advisories, analysis.

scry

Attackers weaponise vulnerabilities like this against internet-exposed services. See what is exposed on your perimeter with a free passive scan.

Free scan