GHSA-g842-9rc4-69pw

Suggest an improvement
Source
https://github.com/advisories/GHSA-g842-9rc4-69pw
Import Source
https://github.com/github/advisory-database/blob/main/advisories/github-reviewed/2026/10/GHSA-g842-9rc4-69pw/GHSA-g842-9rc4-69pw.json
JSON Data
https://api.osv.dev/v1/vulns/GHSA-g842-9rc4-69pw
Aliases
Downstream
Published
2026-10-22T15:57:17Z
Modified
2026-10-22T16:15:47Z
Severity
  • 7.1 (High) CVSS_V4 - CVSS:4.0/AV:N/AC:L/AT:N/PR:N/UI:P/VC:N/VI:N/VA:H/SC:N/SI:N/SA:N CVSS Calculator
Summary
Pillow: Decompression bomb check bypass in SpiderImagePlugin.seek() leads to unbounded allocation DoS
Details

Summary

SpiderImagePlugin's seek() bypasses the decompression bomb check, allowing a tiny (<1KB) crafted SPIDER stack file to trigger a multi-gigabyte allocation on im.load().

Affected versions

All versions up to and including current HEAD (v13.0.0.dev0, commit e7a7ea84)

Root cause

Image.open() runs Image._decompression_bomb_check(im.size) exactly once, in _open_core (src/PIL/Image.py:3668), right after the initial _open().

SPIDER stack files are multi-frame: SpiderImageFile.seek(frame) (SpiderImagePlugin.py:179-190) computes an attacker-influenced stkoffset and calls self._open() AGAIN directly (line 190) — NOT through Image.open(). _open() re-parses a fresh 27-float header at that offset and reassigns:

self._size = int(h[12]), int(h[2])      # SpiderImagePlugin.py:131

straight from unvalidated header floats (isSpiderHeader only checks internal labrec*lenbyt==labbyt consistency, never bounds nsam/nrow). No bomb check runs on this new size.

On the subsequent load(), ImageFile.load_prepare() (ImageFile.py:436-437) executes self.im = Image.core.new(self.mode, self.size) with the unchecked, attacker-chosen size. Mode is always "F" (4 bytes/pixel), so e.g. 40000x40000 = 6.4 GB.

Why this is a real bug

Sibling multi-frame plugins DO re-check on their alternate paths:

  • GifImagePlugin.py:286 - Image._decompression_bomb_check(self._size) (in seek)
  • TiffImagePlugin.py:1309 - Image._decompression_bomb_check(self._tile_size)
  • IcnsImagePlugin.py:121/138, IcoImagePlugin.py:236/240 (sub-image selection)

SpiderImagePlugin has NO bomb check anywhere. This is the same class of bug just fixed for GdImageFile (GHSA-phj9-mv4w-65pm) and the FontFile classes (GHSA-5x94/8v84/45hq): an allocation reached on a non-Image.open() path sized by an attacker header field, independent of the one-time pixel bomb check.

Reproduction

Python 3.13, Pillow HEAD e7a7ea84

Attached: pillow_poc_spider_bomb.py

Sets Image.MAX_IMAGE_PIXELS=5000, then:

  • CONTROL: Image.open(standalone 100x100 SPIDER) -> DecompressionBombWarning fires correctly.
  • BYPASS: Image.open(stack, frame0=1x1) passes; im.seek(1) sets size (100,100) with NO DecompressionBombWarning/Error -> the check is bypassed.

Real-world impact: a large frame-1 nsam/nrow (e.g. 40000x40000) causes im.load() to allocate ~6.4 GB (mode F) with the bomb check fully bypassed, from a file under 1 KB.

Suggested fix

Call Image._decompression_bomb_check(self.size) at the end of SpiderImageFile._open() (or in seek() after _open()), mirroring GifImagePlugin / TiffImagePlugin. Optionally validate nsam/nrow are positive and sane in _open().

Credit: Yazan Balawneh - CyStack Security Team pillow_poc_spider_bomb.py

Database specific
{
    "cwe_ids":  [
        "CWE-400",
        "CWE-409"
    ],
    "github_reviewed":  true,
    "github_reviewed_at":  "2026-10-22T15:57:17Z",
    "nvd_published_at":  "2026-10-21T21:20:31Z",
    "severity":  "HIGH"
}
References

Affected packages

PyPI / pillow

Package

Affected ranges

Type
ECOSYSTEM
Events
Introduced
0 Unknown introduced version / All previous versions are affected
Fixed
13.0.0

Affected versions

1.*
1.0
1.1
1.2
1.3
1.4
1.5
1.6
1.7.0
1.7.1
1.7.2
1.7.3
1.7.4
1.7.5
1.7.6
1.7.7
1.7.8
2.*
2.0.0
2.1.0
2.2.0
2.2.1
2.2.2
2.3.0
2.3.1
2.3.2
2.4.0
2.5.0
2.5.1
2.5.2
2.5.3
2.6.0
2.6.1
2.6.2
2.7.0
2.8.0
2.8.1
2.8.2
2.9.0
3.*
3.0.0
3.1.0.rc1
3.1.0rc1
3.1.0
3.1.1
3.1.2
3.2.0
3.3.0
3.3.1
3.3.2
3.3.3
3.4.0
3.4.1
3.4.2
4.*
4.0.0
4.1.0
4.1.1
4.2.0
4.2.1
4.3.0
5.*
5.0.0
5.1.0
5.2.0
5.3.0
5.4.0.dev0
5.4.0
5.4.1
6.*
6.0.0
6.1.0
6.2.0
6.2.1
6.2.2
7.*
7.0.0
7.1.0
7.1.1
7.1.2
7.2.0
8.*
8.0.0
8.0.1
8.1.0
8.1.1
8.1.2
8.2.0
8.3.0
8.3.1
8.3.2
8.4.0
9.*
9.0.0
9.0.1
9.1.0
9.1.1
9.2.0
9.3.0
9.4.0
9.5.0
10.*
10.0.0
10.0.1
10.1.0
10.2.0
10.3.0
10.4.0
11.*
11.0.0
11.1.0
11.2.1
11.3.0
12.*
12.0.0
12.1.0
12.1.1
12.2.0
12.3.0

Database specific

source
"https://github.com/github/advisory-database/blob/main/advisories/github-reviewed/2026/10/GHSA-g842-9rc4-69pw/GHSA-g842-9rc4-69pw.json"