{"schema":"threatline.record/2","record":{"id":"CVE-2026-96637","aliases":["GHSA-g842-9rc4-69pw"],"summary":"Pillow: Decompression bomb check bypass in SpiderImagePlugin.seek() leads to unbounded allocation DoS","details":"## Summary\nSpiderImagePlugin's seek() bypasses the decompression bomb check, allowing a tiny (<1KB) crafted SPIDER stack file to trigger a multi-gigabyte allocation on im.load().\n\n## Affected versions\nAll versions up to and including current HEAD (v13.0.0.dev0, commit e7a7ea84)\n\n## Root cause\nImage.open() runs Image._decompression_bomb_check(im.size) exactly once, in _open_core (src/PIL/Image.py:3668), right after the initial _open(). \n\nSPIDER 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:\n\n    self._size = int(h[12]), int(h[2])      # SpiderImagePlugin.py:131\n\nstraight from unvalidated header floats (isSpiderHeader only checks internal labrec*lenbyt==labbyt consistency, never bounds nsam/nrow). No bomb check runs on this new size.\n\nOn 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.\n\n## Why this is a real bug\nSibling multi-frame plugins DO re-check on their alternate paths:\n- GifImagePlugin.py:286 - Image._decompression_bomb_check(self._size) (in seek)\n- TiffImagePlugin.py:1309 - Image._decompression_bomb_check(self._tile_size)\n- IcnsImagePlugin.py:121/138, IcoImagePlugin.py:236/240 (sub-image selection)\n\nSpiderImagePlugin 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.\n\n## Reproduction\nPython 3.13, Pillow HEAD e7a7ea84\n\nAttached: pillow_poc_spider_bomb.py\n\nSets Image.MAX_IMAGE_PIXELS=5000, then:\n- CONTROL: Image.open(standalone 100x100 SPIDER) -> DecompressionBombWarning fires correctly.\n- BYPASS: Image.open(stack, frame0=1x1) passes; im.seek(1) sets size (100,100) with NO DecompressionBombWarning/Error -> the check is bypassed.\n\nReal-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.\n\n## Suggested fix\nCall 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().\n\nCredit: Yazan Balawneh - CyStack Security Team \n[pillow_poc_spider_bomb.py](https://github.com/user-attachments/files/30244916/pillow_poc_spider_bomb.py)","categories":["Libraries & packages"],"product":"pillow","vendor":"python-pillow","ecosystem":"pip","affected_ranges":[{"source":"GitHub Advisory Database","source_url":"https://github.com/advisories/GHSA-g842-9rc4-69pw","source_modified_at":"2026-10-22T15:57:18Z","fetched_at":"2026-10-23T18:42:43.628194Z","package":{"ecosystem":"pip","name":"pillow"},"range":"< 13.0.0"},{"source":"CVE List","source_url":"https://www.cve.org/CVERecord?id=CVE-2026-96637","source_modified_at":"2026-10-23T21:18:59.858Z","fetched_at":"2026-10-23T21:47:51.402276Z","product":"Pillow","vendor":"python-pillow","versions":[{"version":"< 13.0.0","status":"affected"}],"defaultStatus":null},{"source":"OSV","source_url":"https://osv.dev/vulnerability/GHSA-g842-9rc4-69pw","source_modified_at":"2026-10-22T16:15:47.750329011Z","fetched_at":"2026-10-23T18:45:31.882637Z","package":{"ecosystem":"PyPI","name":"pillow","purl":"pkg:pypi/pillow"},"ranges":[{"events":[{"introduced":"0"},{"fixed":"13.0.0"}],"type":"ECOSYSTEM"}],"versions":["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","10.0.0","10.0.1","10.1.0","10.2.0","10.3.0","10.4.0","11.0.0","11.1.0","11.2.1","11.3.0","12.0.0","12.1.0","12.1.1","12.2.0","12.3.0","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"]}],"fixed_versions":[{"source":"GitHub Advisory Database","source_url":"https://github.com/advisories/GHSA-g842-9rc4-69pw","source_modified_at":"2026-10-22T15:57:18Z","fetched_at":"2026-10-23T18:42:43.628194Z","package":{"ecosystem":"pip","name":"pillow"},"version":"13.0.0"},{"source":"OSV","source_url":"https://osv.dev/vulnerability/GHSA-g842-9rc4-69pw","source_modified_at":"2026-10-22T16:15:47.750329011Z","fetched_at":"2026-10-23T18:45:31.882637Z","package":{"ecosystem":"PyPI","name":"pillow","purl":"pkg:pypi/pillow"},"version":"13.0.0"}],"cvss":7.1,"severity":"High","kev":{"listed":false},"epss":{"probability":0.00333,"percentile":0.25364,"score_date":"2026-10-23"},"published_at":"2026-10-21T21:01:20.249Z","modified_at":"2026-10-23T21:18:59.858Z","provenance":[{"source":"GitHub Advisory Database","url":"https://github.com/advisories/GHSA-g842-9rc4-69pw","fetched_at":"2026-10-23T18:42:43.628194Z","source_modified_at":"2026-10-22T15:57:18Z"},{"source":"CVE List","url":"https://www.cve.org/CVERecord?id=CVE-2026-96637","fetched_at":"2026-10-23T21:47:51.402276Z","source_modified_at":"2026-10-23T21:18:59.858Z"},{"source":"OSV","url":"https://osv.dev/vulnerability/GHSA-g842-9rc4-69pw","fetched_at":"2026-10-23T18:45:31.882637Z","source_modified_at":"2026-10-22T16:15:47.750329011Z"},{"source":"EPSS","url":"https://api.first.org/data/v1/epss?cve=CVE-2026-96637","fetched_at":"2026-10-23T18:42:43.628194Z","source_modified_at":"2026-10-23"}],"sources":["GitHub Advisory Database","CVE List","OSV","EPSS"],"references":[{"source":"CVE List","url":"https://github.com/python-pillow/Pillow/security/advisories/GHSA-g842-9rc4-69pw","tags":["x_refsource_CONFIRM"]},{"url":"https://nvd.nist.gov/vuln/detail/CVE-2026-96637","source":"GitHub Advisory Database"},{"source":"CVE List","url":"https://github.com/python-pillow/Pillow/pull/10076","tags":["x_refsource_MISC"]},{"source":"CVE List","url":"https://github.com/python-pillow/Pillow/commit/7cb0e02389d8aac2a60896a490f572db0b07b841","tags":["x_refsource_MISC"]},{"source":"CVE List","url":"https://github.com/python-pillow/Pillow/releases/tag/13.0.0","tags":["x_refsource_MISC"]},{"url":"https://github.com/advisories/GHSA-g842-9rc4-69pw","source":"GitHub Advisory Database"}],"locations":[],"motoko_assessment":{"status":"requires_architecture_review","automatic_remediation":false},"cve_state":"PUBLISHED","ssvc":{"exploitation":"none","automatable":"yes","technical_impact":"partial","assessed_at":"2026-10-23T17:32:50.503938Z"},"classification":{"method":"product-first software-layer rules","rules_version":"2.1","matched_on":"product","confidence":"heuristic","reviewed":false},"change_timestamp":"2026-10-23T21:18:59.858Z","content_hash":"07e4092953e174ca53a3ea33735a4e70d8e94ae20a9e54c31d79a71c922e3ecb"}}
