| FazBrowse GitHub Viewer | Trending | | Home |
| Tools: [Download Repo ZIP] [Original HTTPS Page] |
Sorry, something went wrong.
⚠️ Artifact update problemRenovate failed to update an artifact related to this branch. You probably do not want to merge this PR as-is. ♻ Renovate will retry this branch, including artifacts, only when one of the following happens:
The artifact failure details are included below: File name: uv.lockCommand failed: uv lock --upgrade-package pillow
Using CPython 3.13.14 interpreter at: /opt/containerbase/tools/python/3.13.14/bin/python3
× No solution found when resolving dependencies for split (markers:
│ python_full_version >= '3.12' and python_full_version < '3.14'):
╰─▶ Because moviepy>=2.2.0 depends on pillow>=9.2.0,<12.0 and moviepy==2.1.2
depends on pillow>=9.2.0,<11.0, we can conclude that moviepy>=2.1.2
depends on pillow>=9.2.0,<12.0.
And because dreadnode[all] depends on moviepy>=2.1.2, we can conclude
that dreadnode[all] depends on pillow>=9.2.0,<12.0.
And because dreadnode[all] depends on pillow>=12.3.0,<12.4.0 and your
project requires dreadnode[all], we can conclude that your project's
requirements are unsatisfiable.
|
Sorry, something went wrong.
| datasource | package | from | to | | ---------- | ------- | ------ | ------ | | pypi | pillow | 11.3.0 | 12.3.0 |
| Back | FazBrowse Home | New Git URL |
This PR contains the following updates:
Pillow affected by out-of-bounds write when loading PSD images
CVE-2026-25990 / GHSA-cfh3-3jmp-rvhc
More informationDetails
Impact
An out-of-bounds write may be triggered when loading a specially crafted PSD image. Pillow >= 10.3.0 users are affected.
Patches
Pillow 12.1.1 will be released shortly with a fix for this.
Workarounds
Image.open() has a formats parameter that can be used to prevent PSD images from being opened.
References
Pillow 12.1.1 will add release notes at https://pillow.readthedocs.io/en/stable/releasenotes/index.html
Severity
References
This data is provided by the GitHub Advisory Database (CC-BY 4.0).
FITS GZIP decompression bomb in Pillow
CVE-2026-40192 / GHSA-whj4-6x5x-4v2j
More informationDetails
Impact
Pillow did not limit the amount of GZIP-compressed data read when decoding a FITS image, making it vulnerable to decompression bomb attacks. A specially crafted FITS file could cause unbounded memory consumption, leading to denial of service (OOM crash or severe performance degradation).
Patches
The amount of data read is now limited to the necessary amount.
Fixed in Pillow 12.2.0 (PR #9521).
Workarounds
Avoid Pillow >= 10.3.0, < 12.2.0
Only open specific image formats, excluding FITS.
Severity
References
This data is provided by the GitHub Advisory Database (CC-BY 4.0).
Pillow has a heap buffer overflow with nested list coordinates
CVE-2026-42309 / GHSA-5xmw-vc9v-4wf2
More informationDetails
Passing nested lists as coordinates to APIs that accept coordinates such as ImagePath.Path, ImageDraw.ImageDraw.polygon and ImageDraw.ImageDraw.line could cause a heap buffer overflow, as nested lists were recursively unpacked beyond the allocated buffer. Coordinate lists are now validated to contain exactly two numeric coordinates. This was introduced in Pillow 11.2.1.
Severity
References
This data is provided by the GitHub Advisory Database (CC-BY 4.0).
Pillow has an OOB Write with Invalid PSD Tile Extents (Integer Overflow)
CVE-2026-42311 / GHSA-pwv6-vv43-88gr
More informationDetails
Impact
Processing a malicious PSD file could lead to memory corruption, potentially resulting in a crash or arbitrary code execution.
Patches
Patched version: 12.2.0
Pillow 12.1.1 addressed CVE-2026-25990 by adding checks for tile extents in PSD image decoding/encoding to prevent an out-of-bounds write. However, the bounds checks computed tile extent sums using types susceptible to integer overflow, meaning a PSD image with carefully chosen tile dimensions could produce values that wrap around and bypass the checks, still triggering an out-of-bounds write in src/decode.c and src/encode.c. The fix avoids adding extents together before comparison.
Workarounds
Use any version but affected versions: >= 10.3.0, < 12.2.0
Resources
Severity
References
This data is provided by the GitHub Advisory Database (CC-BY 4.0).
Pillow has an integer overflow when processing fonts
CVE-2026-42308 / GHSA-wjx4-4jcj-g98j
More informationDetails
If a font advances for each glyph by an exceeding large amount, when Pillow keeps track of the current position, it may lead to an integer overflow. This has been fixed.
Severity
References
This data is provided by the GitHub Advisory Database (CC-BY 4.0).
Pillow has a PDF Parsing Trailer Infinite Loop (DoS)
CVE-2026-42310 / GHSA-r73j-pqj5-w3x7
More informationDetails
Impact
An attacker can supply a malicious PDF that causes the process to hang indefinitely, consuming 100% CPU and making the application unresponsive.
Patches
Patched version: 12.2.0.
PdfParser (introduced in Pillow 4.2.0) follows Prev pointers in PDF trailers to read cross-reference sections. If a
trailer's Prev pointer references an offset that has already been processed — either pointing to itself or forming a
longer cycle — the parser enters an infinite loop. Pillow now tracks previously processed trailer offsets and raises an
error if a cycle is detected.
Workarounds
Use any version but the affected versions: >= 4.2.0, < 12.2.0
Resources
Severity
References
This data is provided by the GitHub Advisory Database (CC-BY 4.0).
Pillow: Out-of-bounds read via attacker-controlled row stride on Pillow's mmap path (McIdas AREA files)
CVE-2026-54058 / GHSA-62p4-gmf7-7g93
More informationDetails
Summary
When Pillow loads an uncompressed image whose tile uses the raw codec and a mode in Image._MAPMODES, and the image was opened from a filename, it memory-maps the file and builds the image's row pointers directly into the mapping via PyImaging_MapBuffer (src/map.c). The per-row spacing (stride) is taken from the tile arguments. map.c validates offset + ysize*stride <= buffer_len but never checks that stride is at least the natural row width xsize * pixelsize.
The McIdas AREA plugin (McIdasImagePlugin.py) derives stride, offset, xsize, and ysize directly from attacker-controlled 32-bit header words with no validation. By supplying a stride far smaller than the row width, an attacker makes each row pointer read xsize*pixelsize bytes that run past the mapped region. Accessing the pixels (e.g. Image.tobytes(),
getpixel, convert, save) then reads adjacent process memory (information disclosure) or faults (SIGBUS, denial of service).
Complete Code Trace
Step 1: McIdasImageFile._open - turns attacker header words into image size, file offset, and row stride with no validation.
Step 2: ImageFile.load (mmap branch) - selects mmap and delegates to map_buffer.
Step 3: PyImaging_MapBuffer - builds row pointers at stride spacing into the mmap; validates everything except stride >= row width.
im->linesize (the number of bytes any consumer reads per row) is xsize * pixelsize = 200000, but the row pointers are only stride = 1 byte apart and the buffer is only offset + ysize*stride = 2 bytes "claimed". Nothing reconciles the two.
Step 4: pixel access (Image.tobytes() → raw encoder copy1) - reads linesize bytes from im->image[0], i.e. xsize bytes starting at view.buf + offset, running far past the mmap.
Chain Summary
SOURCE: McIdas AREA header words w[9],w[10],w[11],w[14],w[15],w[34] (Image.open on a path) ↓ McIdasImagePlugin._open: stride = w[15]+w[10]*w[11]*w[14] -> attacker sets stride=1 [McIdasImagePlugin.py:66] ↓ tile = ("raw", (0,0,xsize,1), offset, ("L", 1, 1)) [McIdasImagePlugin.py:68] GADGET: ImageFile.load mmap branch -- only checks offset+ysize*stride<=len <- BUG: no stride>=linesize check [ImageFile.py:343] ↓ core.map_buffer(map, (xsize,1), "raw", offset, ("L",1,1)) [ImageFile.py:346] SINK: PyImaging_MapBuffer: im->image[0] = view.buf + offset + 0*stride; linesize=xsize [map.c:134] ↓ Image.tobytes() raw "L" encoder reads linesize (=xsize) bytes from im->image[0] IMPACT: reads xsize bytes from a tiny mmap -> OOB read of adjacent process memory (leak) or SIGBUS (DoS)Proof of Concept
See attached poc.zip
Impact on a Parent Application
Any application that opens image files supplied by users from a path on disk (the common pattern: save upload to a temp file, then Image.open(path)), has the default plugin set (McIdas is registered by default), and subsequently reads/returns/re-encodes the decoded pixels (thumbnailing, format conversion, serving a preview), is exposed:
Suggested fix
Core fix in src/map.c (PyImaging_MapBuffer): reject offset < 0 and stride < im->linesize. Defense-in-depth in McIdasImagePlugin._open: reject offset < 0 or stride < xsize*pixelsize .
Severity
References
This data is provided by the GitHub Advisory Database (CC-BY 4.0).
Pillow: FontFile.compile(): Image.new() called without _decompression_bomb_check()
CVE-2026-54060 / GHSA-5x94-69rx-g8h2
More informationDetails
Description
PIL/FontFile.py FontFile.compile() assembles per-glyph images into a single combined bitmap using Image.new("1", (xsize, ysize)) without calling Image._decompression_bomb_check(). This is the base-class method shared by both BdfFontFile and PcfFontFile, and it is triggered whenever a loaded font is converted to an ImageFont or saved.
Neither BdfFontFile.BdfFontFile(fp) nor PcfFontFile.PcfFontFile(fp) is registered with Image.register_open(), so Pillow's standard decompression bomb guard never fires for font objects. The compile step is the final opportunity to check the combined allocation — and it has no check.
Vulnerable code (PIL/FontFile.py lines ~64–92):
"Slow accumulation" attack — per-glyph dimensions stay BELOW warning threshold:
With PCF-maximum glyph height (65,535):
Steps to reproduce
Proof of Concept script:
Expected output:
[OK] bomb check WOULD block (800, 224000): Image size (179200000 pixels) exceeds limit of 178956970 pixels, could be decompression bomb DOS attack. [BYPASS] compile() succeeded: bitmap=(800, 224000) pixels=179,200,000 (1.001× DecompressionBombError threshold) No DecompressionBombError raised at any point.Verified live on Pillow 12.2.0 — compile() succeeds with no exception.
Real-world trigger using BDF font file:
Attack scenarios:
Impact
Affected call paths:
Neither BdfFontFile nor PcfFontFile is loaded via Image.open(), so the standard decompression bomb guard is entirely absent from the font loading code path. compile() is the only point where the combined allocation size is known, and it has no check.
Confirmed unpatched on python-pillow/Pillow main branch as of 2026-06-08.
Severity
References
This data is provided by the GitHub Advisory Database (CC-BY 4.0).
Pillow PcfFontFile._load_bitmaps(): Image.frombytes() called without _decompression_bomb_check() — bomb protection bypass via PCF font loading
CVE-2026-54059 / GHSA-8v84-f9pq-wr9x
More informationDetails
Description
PIL/PcfFontFile.py _load_bitmaps() (line 227) reads glyph dimensions from the PCF METRICS section and passes them directly to Image.frombytes() without calling Image._decompression_bomb_check(). Dimensions originate from unsigned 16-bit values:
Maximum exploitable pixel count: 65,535 × 131,070 = 8,589,734,450 pixels — 48× the DecompressionBombError threshold.
Vulnerable code (PIL/PcfFontFile.py line 224–227):
Image.frombytes() calls Image.new() first (allocating the full C-heap buffer), then attempts to fill it. This creates two distinct attack paths:
Steps to reproduce
Proof of Concept script:
Expected output:
[Image.open() path] BLOCKED by DecompressionBombError [*] PCF file size : 148 bytes [*] Glyph size : 14000 x 14000 = 196,000,000 pixels [*] C-heap target : 23 MB (mode '1' = 1 bit/pixel) [!] CONFIRMED (transient): ValueError after allocation C-heap allocation of ~23 MB occurred before exceptionAmplification table:
Impact
Severity
References
This data is provided by the GitHub Advisory Database (CC-BY 4.0).
Pillow BdfFontFile: Image.new() called without _decompression_bomb_check() — bomb protection bypass via font loading
CVE-2026-55379 / GHSA-45hq-cxwh-f6vc
More informationDetails
Summary
PIL/BdfFontFile.py bdf_char() (lines 84–88) reads the BBX width height field from a BDF font file and passes the dimensions directly to Image.new() without calling Image._decompression_bomb_check(). This completely bypasses Pillow's documented decompression bomb protection.
Image.open() enforces MAX_IMAGE_PIXELS = 89,478,485 and raises DecompressionBombError for images exceeding 2 × MAX = 178,956,970 pixels. The BDF font loading path calls Image.new() directly, which only calls _check_size() (validates >= 0) — no pixel count limit.
Vulnerable code (PIL/BdfFontFile.py lines 84–88):
Attack trigger: A BDF glyph with BBX 20000 20000 and an empty BITMAP section causes Image.frombytes() to raise ValueError, then Image.new("1", (20000, 20000)) allocates 50 MB of C-heap silently. Image.open() would raise DecompressionBombError for the same dimensions.
Steps to reproduce
Minimal malicious BDF file (270 bytes):
Proof of Concept script:
Expected output:
[Image.open() path] BLOCKED by DecompressionBombError [*] BDF file size : 270 bytes [*] Glyph size : 20000 x 20000 = 400,000,000 pixels [*] C-heap target : 47 MB (mode '1' = 1 bit/pixel) [!] CONFIRMED: BdfFontFile loaded silently — 47 MB allocated Image.open() path would have raised DecompressionBombErrorAmplified attack (multiple glyphs):
A BDF file defining 256 glyphs each at BBX 8000 8000 causes 256 × 7.6 MB = ~1.95 GB total C-heap allocation — all silently, bypassing documented bomb protection.
Impact
Severity
References
This data is provided by the GitHub Advisory Database (CC-BY 4.0).
Pillow GdImageFile._open(): image dimensions accepted without _decompression_bomb_check()
CVE-2026-55380 / GHSA-phj9-mv4w-65pm
More informationDetails
Description
PIL/GdImageFile.py GdImageFile._open() reads image dimensions from the GD 2.x header and stores them in self._size without calling Image._decompression_bomb_check(). Because GdImageFile is not registered with Image.register_open(), it never passes through the standard Image.open() code path that enforces Pillow's decompression bomb guard. The plugin exposes its own entry point — PIL.GdImageFile.open(fp) — which directly instantiates the class, fully bypassing the documented protection.
Vulnerable code (PIL/GdImageFile.py lines 50–61):
When load() is subsequently called on the returned image object:
Dimension arithmetic:
Comparison with safe sibling plugin (WalImageFile):
WalImageFile is in the same category — not registered with Image.open(), loaded via its own open() helper. It was previously patched with the correct fix:
GdImageFile was never updated to match, leaving a gap in protection.
Steps to reproduce
Proof of Concept script:
Expected output:
[BLOCKED] Image.open() path: Image size (4294836225 pixels) exceeds limit of 178956970 pixels, could be decompression bomb DOS attack. [BYPASS] GdImageFile.open() succeeded: size=(65535, 65535), mode=P No _decompression_bomb_check called — 4.3 GB allocation not blocked [INFO] load() OSError (no pixel data) — but C-heap allocation already attempted [MATH] 4,294,836,225 pixels = 24.0× error threshold [MATH] Attack file: 1,037 bytes onlyVerified live on Pillow 12.2.0.
Two attack paths:
For the transient path, a 1,037-byte file is all that is needed. The attacker does not need to upload a large file.
Real-world scenario:
Impact
Any service that calls PIL.GdImageFile.open(user_file) followed by .load() (or any lazy-load trigger) is vulnerable. Because the attack requires only a 1,037-byte file, network bandwidth is not a constraint.
Confirmed unpatched on python-pillow/Pillow main branch as of 2026-06-08.
Severity
References
This data is provided by the GitHub Advisory Database (CC-BY 4.0).
Pillow: WindowsViewer.get_command() OS command injection via unescaped shell path
CVE-2026-55798 / GHSA-4x4j-2g7c-83w6
More informationDetails
1. Summary
WindowsViewer.get_command() constructs a cmd.exe shell command by directly embedding a
file path into an f-string without escaping. The result is passed to
subprocess.Popen(..., shell=True). Shell metacharacters in the file path — most
importantly a double-quote (") that breaks out of the wrapping, followed by & — allow
injection of arbitrary cmd.exe commands.
The macOS equivalent (MacViewer) correctly applies shlex.quote() to the same parameter.
The Linux equivalent (UnixViewer) does likewise. Windows is the only platform missing this
protection, despite shlex.quote being already imported on line 21 of ImageShow.py.
2. Vulnerable Code
File: src/PIL/ImageShow.py, lines 133–150
Contrast with macOS — SAFE (line 164–168):
Cross-platform summary:
shlex.quote is imported on line 21. Its omission from the Windows path is a clear
oversight, not a deliberate design choice.
3. Proof of Concept
A full working PoC is at poc_pillow_injection.py. Key parts:
Part A — Injection string construction (static, no execution):
Part B — Live execution via os.system() (verified on Windows 11, Pillow 12.1.1):
Severity
References
This data is provided by the GitHub Advisory Database (CC-BY 4.0).
Pillow: Heap out-of-bounds write in ImageFilter.RankFilter via integer overflow in ImagingExpand
CVE-2026-59197 / GHSA-xj96-63gp-2gmr
More informationDetails
Summary
Pillow's public rank-filter API can trigger a native heap out-of-bounds write
when given a very large odd filter size.
Minimal public API trigger:
ImageFilter.RankFilter.filter() calls image.expand(size // 2, size // 2)
before rank-filter size validation. With size = 4294967295, the
expansion margin is 2147483647 (INT_MAX). ImagingExpand() then computes
the output dimensions with unchecked signed int arithmetic. On tested builds,
this wraps to a tiny output image and the border-expansion loop writes past the
allocation.
This is reachable through documented public classes (RankFilter,
MedianFilter, MinFilter, and MaxFilter). No private API, ctypes, or custom
Python object is needed.
Details
Current src/PIL/ImageFilter.py:
The expand() call is made before image.rankfilter(...).
Current src/libImaging/Filter.c:ImagingExpand() does not check output-size
overflow:
For a 3x3 image and xmargin = ymargin = INT_MAX, the computed output size
wraps to 1x1 on tested builds. The following loop still uses the huge margin:
src/libImaging/RankFilter.c does contain checks that would reject this size:
But those checks are reached only after RankFilter.filter() has already
called image.expand(...).
Mode "L" produces 1-byte OOB stores. Modes "I" and "F" pro