Attack ChainAIDerived
Hypothetical attack flow derived from CVE metadata – not a confirmed exploit chain
-
AccessIdentify service that composites untrusted PSDs
-
DeliveryUpload 49-byte PSD with huge declared geometry
-
ExploitLibrary sizes buffer from unvalidated header
-
ExecutionMulti-gigabyte allocation attempted
-
ImpactOOM kills worker/host (denial of service)
Vulnerability Assessment
| Weakness |
CWE
ASVS 5.0
V15 - Secure Coding and Architecture Memory allocation limits
|
| Exploitation Conditions | Exploitation requires a service or workflow that invokes psd-tools' PSDImage.composite() or PSDImage.numpy() on attacker-supplied PSD files using a vulnerable version (prior to 1.17.4). The crafted PSD needs only an oversized declared header geometry (width, height, channels, depth, or per-layer rectangles); no authentication, user interaction, or special privileges are needed once the file reaches the parser. What LIMITS exploitation: the target must actually accept and composite/rasterize untrusted PSD input (e.g. an upload-and-thumbnail pipeline) - installations that only process trusted local files, or that never call composite()/numpy(), are not exposed. Impact is confined to availability (out-of-memory crash); there is no data disclosure or code execution. |
| Impact | This is a genuine but bounded availability threat, not an over-inflated high-CVSS finding. The CVSS 7.5 (AV:N/AC:L/PR:N/UI:N/S:U/C:N/I:N/A:H) accurately reflects a remote, unauthenticated, low-complexity denial-of-service with NO confidentiality or integrity impact - the C:N/I:N is important because it caps real-world severity at 'service crash/OOM' rather than data compromise or code execution. CWE-789 (memory allocation from an unvalidated size value) matches the description precisely: attacker-controlled PSD header geometry is used to size buffers before the values are validated against actual file data. No EPSS score, KEV listing, or SSVC decision data was provided in the input. A working exploit DOES effectively exist: the fix commit's test suite embeds a 49-byte base64 proof-of-concept PSD declaring a 5964x10296x6 8-bit canvas (~3.35 GB allocation), so publicly available exploit code exists even though this is not confirmed actively exploited. The realistic risk is elevated only for the specific population that composites/parses untrusted, user-supplied PSD files server-side; for offline or trusted-input use it is negligible. Net: a real, easy-to-trigger DoS against exposed PSD-processing services, but availability-only and dependent on the deployment accepting attacker files. |
| Exploit ScenarioDerived | An attacker uploads a tiny (~49-byte) crafted PSD whose header declares enormous width/height/channel dimensions to a web service that thumbnails or composites user-supplied Photoshop files. When the service calls PSDImage.composite() or PSDImage.numpy(), the library allocates a multi-gigabyte output buffer from the unvalidated header before checking it against the actual file, exhausting memory and triggering an OOM kill of the worker or host. A functional 49-byte PoC is already published in the project's own fix-commit test suite, making reproduction trivial. |
Get an e-mail when this CVE is exploited, patched or re-scored. Free account.
Alert meAnalysisAIv1 – Sep 22, 2026
Denial of service in psd-tools before 1.17.4: PSDImage.composite() and PSDImage.numpy() size their output buffers directly from the geometry declared in an untrusted PSD header (width, height, channels, depth, and per-layer rectangles) before validating those values against the bytes actually present in the file, so a 49-byte crafted PSD can force a roughly 3.35 GB allocation. Any service that composites or rasterizes attacker-supplied PSD files - an upload-and-thumbnail pipeline, for example - can be driven out of memory and terminated, and no authentication, privileges, or user interaction are required (CVSS:3.1/AV:N/AC:L/PR:N/UI:N/S:U/C:N/I:N/A:H). Impact is confined to availability, no public exploit has been identified at time of analysis, and the issue is fixed in 1.17.4.
RemediationAI
Vendor-released patch: 1.17.4 - upgrade with 'pip install --upgrade psd-tools==1.17.4' (or later) as documented in the advisory at https://github.com/psd-tools/psd-tools/security/advisories/GHSA-8q6g-vjhf-jp8m and the v1.17.4 release tag; the data-aware guard that rejects tiny files declaring huge canvases is the actual fix, so pinning to a lower version is not sufficient. If upgrading must wait, exploit the patch's own knobs: set psd_tools.api.utils.MAX_ALLOC_BYTES to a concrete byte ceiling in your process configuration - it defaults to None (disabled), so it provides no protection until you set it - accepting the trade-off that legitimate large canvases above the budget will now raise ValueError; and leave psd_tools.compression.MAX_DEGRADED_BYTES at its 16 MiB default with MAX_DEGRADED_RATIO at 1000 (do not set MAX_DEGRADED_BYTES to None, which restores the unbounded black-fill fallback), accepting that large undecodable channels now raise instead of degrading to a black image, while small corrupt channels still warn and black-fill leniently. Operationally, run any PSD parsing or compositing of untrusted input inside a container or cgroup with a hard memory limit so an oversized allocation kills a disposable worker rather than the host, and reject/queue-limit PSD uploads (note that file-size limits are ineffective - the published proof-of-concept input is only 49 bytes, so gate on pixel/channel metadata or isolated worker memory rather than bytes on the wire). If untrusted PSD handling is not a business requirement, the strongest mitigation is to stop passing user-supplied PSDs to PSDImage.composite() and PSDImage.numpy() altogether, since only those paths trigger the excessive allocation; any such feature restriction is a functional trade-off rather than a technical control.
Affected VersionsENISA
Affected Packages
Source: OSV (Open Source Vulnerabilities)
Affects your stack
Affects 1 package in pypi
Checking this CVE against your own stacks and servers is part of the Basic plan and up.
Technical ContextAI · show details
The root cause is CWE-789 (Memory Allocation with Excessive Size Value): psd-tools trusts attacker-controlled header geometry and allocates float/array buffers before confirming that enough pixel data exists to fill them. The vulnerable call chain passed only width and height to check_pixel_size() in psd_tools/api/utils.py from psd_tools/api/numpy_io.py (get_array) and psd_tools/api/pil_io.py (convert_image_data_to_pil), omitting the channel count from the size estimate; per-layer rectangles were likewise used to size per-layer buffers without validation. A second amplifier lived in psd_tools/compression/__init__.py, where a failed decode of a channel fell back to emitting a PSDDecompressionWarning and black-filling a buffer of the declared length, which is why PSDImage.composite() could return a black image instead of raising. The 1.17.4 fix threads channels into check_pixel_size() and adds an opt-in byte budget, psd_tools.api.utils.MAX_ALLOC_BYTES (default None), that rejects allocations whose estimated size (width * height * channels * 4) exceeds the configured ceiling; it also adds MAX_DEGRADED_BYTES = 16 MiB and MAX_DEGRADED_RATIO = 1000 in the compression module to refuse the black-fill fallback whenever the requested length exceeds 16 MiB and is more than 1000x the available input bytes. The upstream regression suite ships a 49-byte base64 PSD declaring 5964 x 10296, 6 channels, 8-bit (about 3.35 GB pre-fix), demonstrating that input file size is no indicator of allocation size. Note that the supplied tags include "Information Disclosure" and "Adobe"; neither matches the assessed vector, which is availability-only (C:N/I:N/A:H), and Adobe refers to the PSD file format rather than the vendor of the affected library.
Know when Python gets its next vulnerability
- Watch products and get an email when something new is published
- Check this CVE against your own stack and servers
- Exploit and PoC references, threat intelligence from 22 sources
No credit card · 7-day full trial
Severity by source
AV:N/AC:L/PR:N/UI:N/S:U/C:N/I:N/A:H
A tiny crafted file processed by a remote service triggers OOM with no auth or interaction (AV:N/AC:L/PR:N/UI:N); impact is availability-only crash, so C:N/I:N/A:H.
Primary rating from Vendor (GitHub_M).
CVSS VectorVendor: GitHub_M
Lifecycle Timeline
2DescriptionCVE.org
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.
Technical POC Analysis
CWE-789 (Memory Allocation with Excessive Size Value).
Full technical POC analysis - root cause, step-by-step exploitation and patch breakdown - is part of the Pro and Business plans.
Executive ViewAI
A denial-of-service flaw in the psd-tools library (versions before 1.17.4) allows anyone who can submit a Photoshop file to crash services that process or rasterize PSD uploads, such as thumbnail generators and media pipelines, by forcing multi-gigabyte memory allocations from a tiny crafted file. Because the attack requires no credentials or user interaction, any internet-facing or customer-facing upload path built on the affected library is exposed to repeated outage attempts. Leadership should care because the impact is service availability and customer trust rather than data theft, and remediation depends on upgrading a widely embedded third-party dependency.
Apply vendor patch (upgrade to psd-tools 1.17.4 or later); until upgrade, enforce upload size limits, per-worker memory caps and timeouts, and isolate or rate-limit PSD compositing services.
Threat Intelligence Overview
How this decision was reached
The engine reads each signal below and applies a fixed list of rules from top to bottom. The first rule that matches sets the recommended action – like a statement, every line is shown.
What every action level means
SSVC AssessmentENISA
Priority Score
Attack Technique
Information disclosure occurs when an application unintentionally exposes sensitive data that aids attackers in reconnaissance or directly compromises security.
Wazuh SIEM platform versions 4.4.0 through 4.9.0 contain an unsafe deserialization vulnerability in the DistributedAPI t
BentoML version 1.4.2 and earlier contains an unauthenticated remote code execution vulnerability through insecure deser
pgAdmin 4 contains critical remote code execution vulnerabilities in the Query Tool download and Cloud Deployment endpoi
The renderLocalView function in render/views.py in graphite-web in Graphite 0.9.5 through 0.9.10 uses the pickle Python
BentoML is a Python library for building online serving systems optimized for AI apps and model inference. Rated critica
OpenSSL before 0.9.8za, 1.0.0 before 1.0.0m, and 1.0.1 before 1.0.1h does not properly restrict processing of ChangeCiph
pyLoad download manager version prior to 0.5.0b3.dev77 exposes the Flask SECRET_KEY through an unauthenticated endpoint.
Langflow (a visual LLM pipeline builder) contains a critical unauthenticated code execution vulnerability (CVE-2026-3301
In Mercurial before 4.1.3, "hg serve --stdio" allows remote authenticated users to launch the Python debugger, and conse
Unauthenticated remote code execution affects Kestra OSS (the open-source event-driven orchestration platform) prior to
Unauthenticated remote code execution in Marimo ≤0.20.4 allows attackers to execute arbitrary system commands via the `/
pyLoad is the free and open-source Download Manager written in pure Python. Rated medium severity (CVSS 5.3), this vulne
EUVD-2026-84808
GHSA-8q6g-vjhf-jp8m
NVD
CVE.org
EPSS
Vulnrichment
Exploit-DB