Skip to main content
VulnerabilityPublished

CVE-2026-62297: ag-psd can exhaust memory when parsing crafted PSD dimensions

Affects ag-psdSource GCVE Database

0
Compare
Authoritative record:CVE-2026-62297· High 7.5

Not known to be exploited · CVSS 7.5 High : upgrade to 31.0.0 soon.

Data as of 14 Nov 2026, 01:05 UTC

CVSS 3.1 base score
7.5High
How severe the flaw is on the 0–10 CVSS scale.

Thin evidence

One scorer or none
CVSS scores by source
CNA (GitHub_M)CVSS 3.17.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:H

Exploitation evidence

  1. Disclosed: evidence found.

    CVE published 30 Oct 2026

  2. Detectable: no evidence on record.

    No public nuclei template indexed

  3. Weaponized: no evidence on record.

    No public exploit code indexed in Metasploit or Exploit-DB

  4. Exploited in the wild: no evidence on record.

    Not in CISA KEV and no source reports exploitation

  5. Observed by OffSeq 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

ProductAffectedFixed in
npmag-psdAffected
  • <31.0.0
Fixed in
  • 31.0.0

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

Community reviews

Loading reviews…