Back to Blog
high SEVERITY3 min read

image-size 1.2.1 DoS: Zero-Valued Dimensions in Image Buffer Parser

A high-severity denial-of-service vulnerability in image-size 1.2.1 allows attackers to crash Node.js services using malicious image buffers with zero-valued dimensions. The fix removes the vulnerable `queue` dependency and tightens dimension validation in version 2.0.3.

O
By Orbis AppSec
•Technically reviewed by Anupam Mediratta•Published September 30, 2026•Reviewed September 30, 2026

Answer Summary

image-size versions before 2.0.3 are vulnerable. An attacker can cause infinite CPU consumption by supplying a crafted image buffer where the width or height field is zero, triggering an unbounded loop in the dimension calculation logic. Upgrade to image-size 2.0.3, which removes the `queue` dependency and adds proper validation for zero-valued dimensions. CWE unknown.

Vulnerability at a Glance

cweN/A
fixUpgrade to image-size 2.0.3; removes `queue` dependency and enforces minimum dimension constraints
riskCPU exhaustion and service unavailability from a single malicious image upload
languageJavaScript (Node.js)
root causeMissing validation for zero-valued width/height fields in image dimension parsing
vulnerabilityDenial of Service via malformed image buffer

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-size 1.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 queue in 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 queue package'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.

Prevention and further reading

Frequently Asked Questions

Does image-size 2.0.3 require Node.js 18 specifically because of the CVE-2025-71329 fix, or was that an unrelated change?

The Node.js 18 requirement was an unrelated breaking change for the 2.x major version. The DoS fix itself could theoretically apply to Node.js 16, but the patched release only targets Node.js 18+.

Why did the fix remove the `queue` dependency entirely rather than upgrading it?

The `queue` package (version 6.0.2) was a direct dependency of image-size 1.2.1 but is absent from 2.0.3. The maintainers eliminated it as part of the architectural changes that fixed the unbounded processing bug.

If my application only processes images from trusted internal sources, am I still exposed to CVE-2025-71329?

Yes—any code path that calls image-size's dimension parsing on arbitrary buffers is vulnerable, regardless of source. A compromised internal asset or supply chain injection could still reach the affected function.

View the Security Fix

Check out the pull request that fixed this vulnerability

View PR #6

Related Articles

critical

Lampa Desktop Auto-Update Heuristic Bypass: Execution of Unverified

Lampa Desktop's auto-update mechanism downloaded JavaScript and CSS from `raw.githubusercontent.com` using only heuristic validation—file size thresholds and string pattern matching—that attackers could trivially satisfy. The fix introduces cryptographic integrity verification by cross-referencing Git blob hashes from the GitHub Contents API, ensuring downloaded code matches the repository's authoritative state before execution.

high

adm-zip 0.6.0 Preserves SUID Bits From ZIPs: CVE-2026-102282

The `adm-zip` dependency resolved to 0.6.0 in this project's dependency tree, a version affected by CVE-2026-102282: during extraction it applies the Unix permission bits stored in each ZIP entry's external file attributes verbatim, including the setuid (`04000`), setgid (`02000`), and sticky bits. An attacker who controls an archive passed to `extractAllTo()` or `extractEntryTo()` can therefore have the extractor create a setuid binary owned by whatever user the extraction process runs as. The

high

requestInput() Type Confusion: NaN and Object Bypass in JavaScript

The `requestInput()` utility function lacked validation on its `type` parameter and failed to handle `NaN` results from float conversions, creating a type confusion weakness. An attacker could supply malformed inputs that propagate unhandled `NaN` values or unexpected object types through the type system. The fix adds explicit guards against `NaN` type parameters and rejects non-primitive type values.

critical

No Rate Limit on /api/uploads/presign Enables DoS

The `/api/uploads/presign` endpoint accepted unlimited concurrent requests to generate storage presigned URLs, giving an attacker a free lever to exhaust storage-provider quotas and server resources. The fix adds an `express-rate-limit` middleware capping each client to 30 requests per minute on that route.

high

CVE-2026-54673: builder-util-runtime Leaks Auth Headers on Redirect

electron-updater and electron-builder rely on builder-util-runtime to fetch update manifests and artifacts over HTTP. A flaw in that shared HTTP executor allowed credential headers attached to the original update-feed request to be re-sent after a redirect, exposing them to any host the redirect pointed to. The project fixes this by upgrading builder-util-runtime to 9.7.0 and collapsing a duplicate, older copy of the package that electron-updater had pinned on its own.

high

picomatch 2.3.1 ReDoS: Extglob Pattern Catastrophic Backtracking

picomatch versions below 2.3.2, 3.0.2, or 4.0.4 contain a Regular Expression Denial of Service vulnerability in extglob pattern parsing. An attacker can cause catastrophic backtracking with patterns containing nested alternations and quantifiers, freezing any Node.js process that evaluates untrusted glob expressions.