CVE-2026-59991
psd-tools: Uncontrolled memory allocation in psd-tools composite/numpy via crafted PSD geometry
psd-tools is a Python package for working with Adobe Photoshop PSD files. Prior to 1.17.4, PSDImage.composite() and PSDImage.numpy() allocated output buffers from attacker-controlled PSD header geometry, including width, height, channels, depth, and per-layer rectangles, before validating those values against the available file data. A tiny crafted PSD could therefore cause multi-gigabyte memory allocation, and PSDImage.composite() could return a black image with only a warning instead of raising an exception. Services that composite untrusted PSD files could be terminated by out-of-memory handling. This issue is fixed in version 1.17.4.
Attack profile
How easy it is to exploit
- Attack vector
- Network
- Complexity
- Low
- Privileges needed
- None
- User interaction
- None
What an attacker can affect
- Confidentiality
- None
- Integrity
- None
- Availability
- High
Exploit likelihood
What each source reports
CVE List Score used
7.5
psd-tools: Uncontrolled memory allocation in psd-tools composite/numpy via crafted PSD geometry
psd-tools is a Python package for working with Adobe Photoshop PSD files. Prior to 1.17.4, PSDImage.composite() and PSDImage.numpy() allocated output buffers from attacker-controlled PSD header geometry, including width, height, channels, depth, and per-layer rectangles, before validating those values against the available file data. A tiny crafted PSD could therefore cause multi-gigabyte memory allocation, and PSDImage.composite() could return a black image with only a warning instead of raising an exception. Services that composite untrusted PSD files could be terminated by out-of-memory handling. This issue is fixed in version 1.17.4.
- Record
CVE-2026-59991- CVSS 3.1
- 7.5 High
CVSS:3.1/AV:N/AC:L/PR:N/UI:N/S:U/C:N/I:N/A:H - Weakness
- CWE-789
- Updated
- 2026-11-02
EUVDEUVD-2026-84808
7.5
psd-tools is a Python package for working with Adobe Photoshop PSD files. Prior to 1.17.4, PSDImage.composite() and PSDImage.numpy() allocated output buffers from attacker-controlled PSD header geometry, including width, height, channels, depth, and per-layer rectangles, before validating those values against the available file data. A tiny crafted PSD could therefore cause multi-gigabyte memory allocation, and PSDImage.composite() could return a black image with only a warning instead of raising an exception. Services that composite untrusted PSD files could be terminated by out-of-memory handling. This issue is fixed in version 1.17.4.
- Record
EUVD-2026-84808- CVSS 3.1
- 7.5 High
CVSS:3.1/AV:N/AC:L/PR:N/UI:N/S:U/C:N/I:N/A:H - Updated
- 2026-11-02
GitHub AdvisoriesGHSA-8q6g-vjhf-jp8m
7.5
psd-tools composite/numpy has uncontrolled memory allocation via crafted PSD geometry
Summary
PSDImage.composite() (and .numpy()) allocate the output image buffer from the PSD's header geometry (width × height × channels × depth, and per-layer rectangles) before validating those values against the actual file contents. A tiny crafted PSD declaring huge dimensions causes a multi-gigabyte allocation. Critically, composite() then returns a (black) image with only a warning, no exception is raised, so a caller cannot detect or guard against it.
Impact
On psd-tools 1.17.2 (latest), default usage, a 49-byte PSD makes composite() commit ~3 GB and return successfully (warning only); .numpy() reaches ~7.5 GB, and the per-layer rectangle is a second lever (up to ~32 GB), all from an input under 100 bytes (input-to-commit amplification over 1000×). Because the buffer is committed before validation and no exception is thrown, any service that composites untrusted PSDs is exposed to denial of service: on a host with less RAM than the attacker-declared geometry the allocation is an unrecoverable OOM-kill.
Steps to reproduce
# pip install psd-tools==1.17.2
from psd_tools import PSDImage
psd = PSDImage.open("psd-psdtools-grammar-d23.psd")
psd.composite() # commits ~3 GB from a 49-byte file and returns (warning only)
PoC (49 bytes), reconstruct with:
base64 -d > psd-psdtools-grammar-d23.psd <<'EOF'
OEJQUwABAAAAAAAAAAYAACg4AAAXTAAIAAMAAAAAAAAAAAAAAAAAAUNIUIFU+yQtDw==
EOF
Verify:
7d8ebf03a54393cb0359ecf4b676d1b08c9a8c6afdd06671ef406d6893cce826 psd-psdtools-grammar-d23.psd
Root cause
The composite/numpy buffer is sized from the declared image (and per-layer) dimensions and channel/depth without checking them against the available data length or a sane maximum.
Suggested fix
Validate the declared dimensions, channel count, and per-layer rectangles against the actual file length (and a configurable maximum pixel/byte budget) before allocating; raise an error on overflow instead of committing the buffer and returning a black image.
- Record
GHSA-8q6g-vjhf-jp8m- CVSS 3.1
- 7.5 High
CVSS:3.1/AV:N/AC:L/PR:N/UI:N/S:U/C:N/I:N/A:H - Weakness
- CWE-789
- Updated
- 2026-11-02
NVD
7.5
psd-tools is a Python package for working with Adobe Photoshop PSD files. Prior to 1.17.4, PSDImage.composite() and PSDImage.numpy() allocated output buffers from attacker-controlled PSD header geometry, including width, height, channels, depth, and per-layer rectangles, before validating those values against the available file data. A tiny crafted PSD could therefore cause multi-gigabyte memory allocation, and PSDImage.composite() could return a black image with only a warning instead of raising an exception. Services that composite untrusted PSD files could be terminated by out-of-memory handling. This issue is fixed in version 1.17.4.
- Record
CVE-2026-59991- CVSS 3.1
- 7.5 High
CVSS:3.1/AV:N/AC:L/PR:N/UI:N/S:U/C:N/I:N/A:H - Weakness
- CWE-789
- Updated
- 2026-11-02
OSV
7.5
psd-tools: Uncontrolled memory allocation in psd-tools composite/numpy via crafted PSD geometry
psd-tools is a Python package for working with Adobe Photoshop PSD files. Prior to 1.17.4, PSDImage.composite() and PSDImage.numpy() allocated output buffers from attacker-controlled PSD header geometry, including width, height, channels, depth, and per-layer rectangles, before validating those values against the available file data. A tiny crafted PSD could therefore cause multi-gigabyte memory allocation, and PSDImage.composite() could return a black image with only a warning instead of raising an exception. Services that composite untrusted PSD files could be terminated by out-of-memory handling. This issue is fixed in version 1.17.4.
- Record
CVE-2026-59991- CVSS 3.1
- 7.5 High
CVSS:3.1/AV:N/AC:L/PR:N/UI:N/S:U/C:N/I:N/A:H - Weakness
- CWE-789
- Updated
- 2026-11-02
OSVDEBIAN-CVE-2026-59991
7.5
psd-tools is a Python package for working with Adobe Photoshop PSD files. Prior to 1.17.4, PSDImage.composite() and PSDImage.numpy() allocated output buffers from attacker-controlled PSD header geometry, including width, height, channels, depth, and per-layer rectangles, before validating those values against the available file data. A tiny crafted PSD could therefore cause multi-gigabyte memory allocation, and PSDImage.composite() could return a black image with only a warning instead of raising an exception. Services that composite untrusted PSD files could be terminated by out-of-memory handling. This issue is fixed in version 1.17.4.
- Record
DEBIAN-CVE-2026-59991- CVSS 3.1
- 7.5 High
CVSS:3.1/AV:N/AC:L/PR:N/UI:N/S:U/C:N/I:N/A:H - Updated
- 2026-11-02
OSVGHSA-8q6g-vjhf-jp8m
7.5
psd-tools composite/numpy has uncontrolled memory allocation via crafted PSD geometry
Summary
PSDImage.composite() (and .numpy()) allocate the output image buffer from the PSD's header geometry (width × height × channels × depth, and per-layer rectangles) before validating those values against the actual file contents. A tiny crafted PSD declaring huge dimensions causes a multi-gigabyte allocation. Critically, composite() then returns a (black) image with only a warning, no exception is raised, so a caller cannot detect or guard against it.
Impact
On psd-tools 1.17.2 (latest), default usage, a 49-byte PSD makes composite() commit ~3 GB and return successfully (warning only); .numpy() reaches ~7.5 GB, and the per-layer rectangle is a second lever (up to ~32 GB), all from an input under 100 bytes (input-to-commit amplification over 1000×). Because the buffer is committed before validation and no exception is thrown, any service that composites untrusted PSDs is exposed to denial of service: on a host with less RAM than the attacker-declared geometry the allocation is an unrecoverable OOM-kill.
Steps to reproduce
# pip install psd-tools==1.17.2
from psd_tools import PSDImage
psd = PSDImage.open("psd-psdtools-grammar-d23.psd")
psd.composite() # commits ~3 GB from a 49-byte file and returns (warning only)
PoC (49 bytes), reconstruct with:
base64 -d > psd-psdtools-grammar-d23.psd <<'EOF'
OEJQUwABAAAAAAAAAAYAACg4AAAXTAAIAAMAAAAAAAAAAAAAAAAAAUNIUIFU+yQtDw==
EOF
Verify:
7d8ebf03a54393cb0359ecf4b676d1b08c9a8c6afdd06671ef406d6893cce826 psd-psdtools-grammar-d23.psd
Root cause
The composite/numpy buffer is sized from the declared image (and per-layer) dimensions and channel/depth without checking them against the available data length or a sane maximum.
Suggested fix
Validate the declared dimensions, channel count, and per-layer rectangles against the actual file length (and a configurable maximum pixel/byte budget) before allocating; raise an error on overflow instead of committing the buffer and returning a black image.
- Record
GHSA-8q6g-vjhf-jp8m- CVSS 3.1
- 7.5 High
CVSS:3.1/AV:N/AC:L/PR:N/UI:N/S:U/C:N/I:N/A:H - Weakness
- CWE-789
- Updated
- 2026-11-02
OSVPYSEC-2026-4139
7.5
psd-tools composite/numpy has uncontrolled memory allocation via crafted PSD geometry
Summary
PSDImage.composite() (and .numpy()) allocate the output image buffer from the PSD's header geometry (width × height × channels × depth, and per-layer rectangles) before validating those values against the actual file contents. A tiny crafted PSD declaring huge dimensions causes a multi-gigabyte allocation. Critically, composite() then returns a (black) image with only a warning, no exception is raised, so a caller cannot detect or guard against it.
Impact
On psd-tools 1.17.2 (latest), default usage, a 49-byte PSD makes composite() commit ~3 GB and return successfully (warning only); .numpy() reaches ~7.5 GB, and the per-layer rectangle is a second lever (up to ~32 GB), all from an input under 100 bytes (input-to-commit amplification over 1000×). Because the buffer is committed before validation and no exception is thrown, any service that composites untrusted PSDs is exposed to denial of service: on a host with less RAM than the attacker-declared geometry the allocation is an unrecoverable OOM-kill.
Steps to reproduce
# pip install psd-tools==1.17.2
from psd_tools import PSDImage
psd = PSDImage.open("psd-psdtools-grammar-d23.psd")
psd.composite() # commits ~3 GB from a 49-byte file and returns (warning only)
PoC (49 bytes), reconstruct with:
base64 -d > psd-psdtools-grammar-d23.psd <<'EOF'
OEJQUwABAAAAAAAAAAYAACg4AAAXTAAIAAMAAAAAAAAAAAAAAAAAAUNIUIFU+yQtDw==
EOF
Verify:
7d8ebf03a54393cb0359ecf4b676d1b08c9a8c6afdd06671ef406d6893cce826 psd-psdtools-grammar-d23.psd
Root cause
The composite/numpy buffer is sized from the declared image (and per-layer) dimensions and channel/depth without checking them against the available data length or a sane maximum.
Suggested fix
Validate the declared dimensions, channel count, and per-layer rectangles against the actual file length (and a configurable maximum pixel/byte budget) before allocating; raise an error on overflow instead of committing the buffer and returning a black image.
- Record
PYSEC-2026-4139- CVSS 3.1
- 7.5 High
CVSS:3.1/AV:N/AC:L/PR:N/UI:N/S:U/C:N/I:N/A:H - Updated
- 2026-11-02
OSVUBUNTU-CVE-2026-59991
7.5
psd-tools is a Python package for working with Adobe Photoshop PSD files. Prior to 1.17.4, PSDImage.composite() and PSDImage.numpy() allocated output buffers from attacker-controlled PSD header geometry, including width, height, channels, depth, and per-layer rectangles, before validating those values against the available file data. A tiny crafted PSD could therefore cause multi-gigabyte memory allocation, and PSDImage.composite() could return a black image with only a warning instead of raising an exception. Services that composite untrusted PSD files could be terminated by out-of-memory handling. This issue is fixed in version 1.17.4.
- Record
UBUNTU-CVE-2026-59991- CVSS 3.1
- 7.5 High
CVSS:3.1/AV:N/AC:L/PR:N/UI:N/S:U/C:N/I:N/A:H - Updated
- 2026-11-02
Affected products
Affected packages
| Package | Affected | Fixed |
|---|---|---|
psd-toolsPyPI |
before 1.17.4 | 1.17.4 |
psd-toolsDebian:12 |
All versions, plus listed versions 1.10.7+dfsg.1-11.10.9+dfsg.1-11.12.0+dfsg.1-11.12.1+dfsg.1-11.14.2+dfsg.1-1 Show 11 moreShow less1.14.3+dfsg.1-11.15.0+dfsg.1-11.16.0+dfsg.1-11.17.0+dfsg.1-11.17.4+dfsg.1-11.9.24+dfsg.1-11.9.28+dfsg.1-11.9.30+dfsg.1-11.9.31+dfsg.1-11.9.32+dfsg.1-11.9.34+dfsg.1-1 |
None known |
psd-toolsDebian:13 |
All versions, plus listed versions 1.10.7+dfsg.1-11.10.7+dfsg.1-1+deb13u11.10.9+dfsg.1-11.12.0+dfsg.1-11.12.1+dfsg.1-1 Show 6 moreShow less1.14.2+dfsg.1-11.14.3+dfsg.1-11.15.0+dfsg.1-11.16.0+dfsg.1-11.17.0+dfsg.1-11.17.4+dfsg.1-1 |
None known |
psd-toolsDebian:14 |
before 1.17.4+dfsg.1-1, plus listed versions 1.10.7+dfsg.1-11.10.9+dfsg.1-11.12.0+dfsg.1-11.12.1+dfsg.1-11.14.2+dfsg.1-1 Show 4 moreShow less1.14.3+dfsg.1-11.15.0+dfsg.1-11.16.0+dfsg.1-11.17.0+dfsg.1-1 |
1.17.4+dfsg.1-1 |
psd-toolsPyPI |
before 1.17.4, plus listed versions 0.1.10.1.20.1.30.1.40.10 Show 45 moreShow less0.20.50.60.70.7.10.80.8.10.8.20.8.30.8.40.90.9.11.01.11.10.01.10.11.10.101.10.111.10.121.10.131.10.21.10.31.10.41.10.51.10.61.10.71.10.81.10.91.11.01.11.11.12.01.12.11.12.21.13.01.13.11.14.01.14.11.14.21.14.31.15.0.post11.16.01.17.01.17.11.17.21.17.3 |
1.17.4 |
psd-toolsUbuntu:24.04:LTS |
All versions, plus listed versions 1.9.28+dfsg.1-11.9.28+dfsg.1-1build11.9.30+dfsg.1-11.9.30+dfsg.1-1build1 |
None known |
psd-toolsUbuntu:26.10 |
All versions, plus listed versions 1.12.1+dfsg.1-11.17.0+dfsg.1-11.17.4+dfsg.1-1 |
None known |
psd-toolsUbuntu:26.04:LTS |
All versions, plus listed versions 1.10.7+dfsg.1-11.10.7+dfsg.1-1build11.10.9+dfsg.1-11.12.0+dfsg.1-11.12.1+dfsg.1-1 |
None known |
History
| Recorded | Changed | Sources |
|---|---|---|
| first indexed | CVE List, EUVD, GitHub Advisories, NVD, OSV |
Dates are when Every CVE recorded each change. Upstream dates may differ.
In short
CVE-2026-59991 is a high vulnerability (CVSS 7.5) in Psd-tools, published September 22, 2026. No source lists public exploit code. EPSS puts the chance of exploitation in the next 30 days at 0.52%, the 44th percentile. Fixed in psd-tools 1.17.4.
References
github.com/psd-tools/psd-tools/security/advisories/GHSA-8q6g-vjhf-jp8m
github.com/psd-tools/psd-tools/commit/a3d9a53ad51e667b5772a4f636ca6f2e16f4b271
github.com/psd-tools/psd-tools/releases/tag/v1.17.4
github.com/advisories/GHSA-8q6g-vjhf-jp8m
github.com/CVEProject/cvelistV5/tree/main/cves/2026/59xxx/CVE-2026-59991.json
nvd.nist.gov/vuln/detail/CVE-2026-59991
Left out here: 68 versions. The JSON record has them.