CVE-2026-62297: ag-psd can exhaust memory when parsing crafted PSD dimensions
Affects ag-psdSource GCVE Database
Not known to be exploited · CVSS 7.5 High : upgrade to 31.0.0 soon.
Data as of 14 Nov 2026, 01:05 UTC
Thin evidence
One scorer or none| CNA (GitHub_M) | CVSS 3.1 | 7.5 |
|---|
- Patch
- Available – fixed in 31.0.0
CVSS:3.1/AV:N/AC:L/PR:N/UI:N/S:U/C:N/I:N/A:HExploitation evidence
Disclosed: evidence found.
CVE published 30 Oct 2026
Detectable: no evidence on record.
No public nuclei template indexed
Weaponized: no evidence on record.
No public exploit code indexed in Metasploit or Exploit-DB
Exploited in the wildExploited: no evidence on record.
Not in CISA KEV and no source reports exploitation
Observed by OffSeq MirageSeen by Mirage: no evidence on record.
No attack traffic recorded by OffSeq Mirage sensors
A missing step is not evidence of safety. Sources: cve.org (opens in a new tab), the Metasploit, Exploit-DB and nuclei-templates index as of 13 Nov 2026.
What to do
Upgrade ag-psd to 31.0.0.
Affected software
| Product | Affected | Fixed in |
|---|---|---|
| npmag-psd | Affected
| Fixed in
|
Check your own hosts for these packages with threat-finder (opens in a new tab), our free open-source scanner.
Description
### Summary readPsd() commits the image/layer buffers from the declared header geometry (width x height x channels x depth, and per-layer rectangles) before validating those values against the actual data. A tiny crafted PSD declaring huge geometry forces a multi-gigabyte allocation. ### Impact On ag-psd 30.2.0, Node 24, a 52-byte PSD makes readPsd(buf) commit ~3.17 GB (measured peak RSS) in ~0.45 s before throwing a catchable RangeError ("Offset is outside the bounds of the DataView") — about 61,000,000x amplification. Because the buffer is committed before validation, the allocation OOM-kills the process before the error on essentially any host (uncatchable), and concurrent requests exhaust memory. Any service reading untrusted PSDs with ag-psd is exposed to a remote DoS. This is distinct from #39 and #206, which involve genuinely large PSDs (memory proportional to real data). Here the input is 52 bytes: the file declares enormous geometry that is never present, so the allocation is driven by an unvalidated header field, not by actual content, an uncontrolled-allocation denial-of-service vulnerability, not proportional memory use. ### Steps to reproduce The PoC is a 52-byte PSD (sha256 a1146a6fabdfef289472f99a56851249e7a46e8d19d4d8bf85fe833e2f0158b6). Reconstruct with: base64 -d > poc.psd <<'EOF' OEJQUwABAAAAAAAAAA0AADcuAAA58wAgAAMAAAAAAAAAAAAAAAAAAdEgNZv+i9bc9ygd2A== EOF Then (commits ~3.17 GB before throwing a catchable RangeError): const { readPsd } = require('ag-psd'); const buf = require('fs').readFileSync('poc.psd'); readPsd(buf.buffer.slice(buf.byteOffset, buf.byteOffset + buf.byteLength)); ### Root cause psdReader.js sizes the off-heap typed-array buffers from the declared header dimensions (and per-layer rectangles, a second independent lever) before validating against the available bytes. ### Suggested fix Validate the declared dimensions, channel count, depth, and per-layer rectangles against the actual input length (and a sane maximum) before allocating.
References
- github.com/Agamnentzar/ag-psd/security/advisories/GHSA-qfx6-q44v-9qqw (opens in a new tab)
- github.com/Agamnentzar/ag-psd/commit/2d7da68400990bae8ba248a065eb45021fa8000a (opens in a new tab)
- github.com/Agamnentzar/ag-psd (opens in a new tab)
- github.com/Agamnentzar/ag-psd/blob/2d7da68400990bae8ba248a065eb45021fa8000a/CHANGELOG.md (opens in a new tab)
- github.com/Agamnentzar/ag-psd/tree/31.0.0 (opens in a new tab)
- nvd.nist.gov/vuln/detail/cve-2026-62297 (opens in a new tab)