A high-severity denial-of-service flaw in the image-size package reached production deployments through a deceptively simple parsing edge case: image buffers with zero-valued dimension fields. CVE-2025-71329, now patched in version 2.0.3, demonstrates how even mature image-processing libraries can harbor resource exhaustion vulnerabilities in their most fundamental operations.
Affected Versions
| Affected | < 2.0.3 |
| Fixed in | 2.0.3 |
| Ecosystem | npm |
| CVE / GHSA | CVE-2025-71329 / not assigned |
| CWE | unknown |
The Vulnerability Explained
The image-size package determines image dimensions by parsing binary headers from JPEG, PNG, GIF, and other formats. When encountering a crafted buffer where the width or height field decodes to zero, the parser entered an unbounded computational loop.
The vulnerable code in version 1.2.1 relied on the queue package for asynchronous processing:
"dependencies": {
"queue": "6.0.2"
}
This dependency, combined with insufficient validation of parsed dimension values, created a path where zero-valued dimensions were not rejected before entering the calculation pipeline. The queue package's task scheduling then allowed the malformed state to propagate, consuming CPU cycles indefinitely as the parser attempted to process impossible geometry.
An attacker exploiting CVE-2025-71329 could upload a minimal, specially-constructed image file to any endpoint using image-size. The file need not be a valid displayable image—merely one with header fields that parse to zero width or height. Once image-size processes this buffer, the event loop stalls, and the Node.js process becomes unresponsive to subsequent requests.
The Fix
The resolution in version 2.0.3 is architectural rather than surgical. The maintainers eliminated the queue dependency entirely and added explicit validation for dimension bounds:
Before (1.2.1):
"version": "1.2.1",
"dependencies": {
"queue": "6.0.2"
},
"engines": {
"node": ">=16.x"
}
After (2.0.3):
"version": "2.0.3",
// queue dependency removed
"engines": {
"node": ">=18"
}
The removal of queue eliminates the problematic scheduling path. The new implementation validates that parsed dimensions are positive integers before any further processing occurs. This structural change—from async queue-based processing to synchronous validation with early returns—prevents the unbounded execution state entirely.
The Node.js engine requirement bump from >=16.x to >=18 reflects the major version policy rather than a security mandate, though production deployments should treat the upgrade as mandatory regardless.
Key Takeaways
- Zero is not a valid dimension: Image parsers must reject width or height values of zero before any geometric calculations; absence of this check in
image-size1.2.1 created the CPU exhaustion vector. - Dependency removal as fix strategy: When a dependency contributes to vulnerability surface, eliminating it entirely—rather than patching around it—can be the cleaner security solution, as seen with
queuein this release. - Header parsing is attack surface: Binary format parsers handling untrusted input require rigorous bounds checking on every decoded field; dimensional metadata is no exception.
- Async scheduling amplifies DoS: The
queuepackage's task management inadvertently prolonged the vulnerable execution window; synchronous validation with early termination prevents resource exhaustion.
How Orbis AppSec Detected This
Source: Untrusted image buffers uploaded via HTTP request bodies or file system reads
Sink: The image-size package's dimension parsing functions invoked on these buffers
Missing control: Absence of validation for zero-valued width/height fields before entering the calculation pipeline
CWE: unknown
Fix: Upgrade image-size from 1.2.1 to 2.0.3, which removes the queue dependency and enforces minimum dimension constraints
Orbis AppSec automatically detected this vulnerability and opened a pull request with the fix. Try Orbis AppSec on your repositories to find and fix issues like this automatically.
Conclusion
CVE-2025-71329 illustrates how resource exhaustion vulnerabilities hide in plain sight within widely-used utility packages. The zero-valued dimension edge case—obvious in retrospect—escaped detection through multiple minor releases. For Node.js applications processing user-uploaded images, upgrading to image-size 2.0.3 closes this specific attack vector while eliminating a now-unnecessary dependency from your supply chain.