Cloudanix VulnDB

CVE-2026-31988

Medium · 5.3

CVSS

5.3

EPSS

0.7%

Published

Mar 11, 2026

CISA due date

—

Cloudanix analysis

Next patch cycle SSVC: Track

A specially made ZIP file can crash some applications that process uploads, causing temporary service disruption.

Exploitation
Remote Unauthenticated
Attacker needs
None
Complexity
Low
Impact
Denial Of Service
Component
Library
Class
Denial of service
Remediation
Upgrade
Effort
Medium
Patch risk
Low

What it actually does

CVE-2026-31988 is a denial-of-service flaw in yauzl 3.2.0, a Node.js ZIP parsing library. The issue is an off-by-one bounds-checking error in the NTFS extended timestamp extra-field parser used by getLastModDate(). A malformed ZIP entry can cause readUInt16LE() to read beyond the end of the Buffer, triggering a Node.js ERR_OUT_OF_RANGE exception. If the consuming application does not safely catch and isolate that exception, the Node.js process or request worker can crash. The vulnerability does not provide code execution, data disclosure, or privilege escalation by itself; the primary impact is application availability.

Why it matters to the business

Applications that accept or process ZIP files may be disrupted by a specially crafted archive, potentially causing failed uploads, worker crashes, job queue failures, or temporary service outages. The CVSS score is moderate and EPSS is low and flat over 30 days, and it is not listed in CISA KEV or associated with ransomware activity, so broad active exploitation is not currently indicated. However, because yauzl is a library embedded in downstream applications, exposure may be indirect and should be addressed wherever ZIP uploads or automated archive processing are internet-facing or business-critical.

How an attack unfolds

An attacker identifies an application feature that accepts ZIP files or retrieves ZIP archives from untrusted sources. They create a ZIP file containing a malformed NTFS extended timestamp extra field whose length and cursor values trigger yauzl 3.2.0's incorrect loop boundary in getLastModDate(). When the application parses entries and calls entry.getLastModDate(), yauzl attempts to read past the Buffer boundary using readUInt16LE(). Node.js raises a RangeError with code ERR_OUT_OF_RANGE. If the application does not catch this exception or runs archive processing in a shared process, the process can terminate or the current worker can fail, causing denial of service for that request, background job, or application instance.

How to fix it

Upgrade yauzl to version 3.2.1 or later wherever it is used directly or transitively. Regenerate lockfiles and redeploy affected Node.js applications, containers, serverless functions, and background workers. If immediate upgrade is not possible, mitigate by validating ZIP files before processing, rejecting malformed extra fields where feasible, wrapping archive parsing and calls to entry.getLastModDate() in exception handling, processing untrusted archives in isolated worker processes, and applying file size, entry count, compression ratio, and request-rate limits to reduce denial-of-service impact. Ensure process supervisors restart failed workers, but do not rely on restarts as the primary fix.

How to confirm the fix worked

Confirm dependency resolution shows yauzl 3.2.1 or later in package-lock.json, npm-shrinkwrap.json, yarn.lock, pnpm-lock.yaml, SBOMs, and deployed artifacts. Run npm ls yauzl, yarn why yauzl, or pnpm why yauzl to identify direct and transitive usage. Verify no deployed container image or build artifact contains node_modules/yauzl at version 3.2.0. Exercise ZIP upload and archive-processing workflows with normal ZIP files and malformed test archives in a non-production environment to confirm the application handles parser exceptions without process termination. Review application logs after deployment to ensure ERR_OUT_OF_RANGE crashes associated with getLastModDate() no longer occur.

Typical attack path

  1. Find an application endpoint, API, integration, or background workflow that processes ZIP archives from users or external sources.
  2. Submit or cause ingestion of a crafted ZIP file containing a malformed NTFS extended timestamp extra field.
  3. Trigger application code that parses ZIP entries using yauzl 3.2.0 and calls entry.getLastModDate().
  4. Cause readUInt16LE() to access data beyond the Buffer boundary due to the off-by-one loop condition.
  5. Generate a Node.js RangeError / ERR_OUT_OF_RANGE exception.
  6. If the exception is uncaught or not isolated, crash the Node.js process, request worker, or archive-processing job, resulting in denial of service.

How to detect it

Look for evidence of unexplained Node.js process crashes or worker failures shortly after ZIP file uploads or archive-ingestion events. Relevant log sources include application logs, upload service logs, API gateway and reverse proxy access logs, Node.js uncaught exception logs, process manager logs such as PM2/systemd/Kubernetes restart events, container stdout/stderr, job queue failure logs, and file-ingestion audit trails. Correlate HTTP requests or ingestion jobs involving .zip files with RangeError exceptions, ERR_OUT_OF_RANGE messages, readUInt16LE stack traces, getLastModDate() calls, or stack frames referencing yauzl. Indicators of attempted exploitation include repeated small ZIP uploads followed by process restarts, archive-processing jobs failing consistently on a specific submitted file, or bursts of 5xx responses after ZIP submissions. Because this issue causes denial of service rather than persistence or code execution, durable host artifacts may be limited to crash logs, uploaded malicious ZIP samples, failed job records, and restart telemetry.

  • ERR_OUT_OF_RANGE
  • RangeError [ERR_OUT_OF_RANGE]
  • The value of "offset" is out of range
  • readUInt16LE
  • getLastModDate
  • node_modules/yauzl
  • node_modules/yauzl/index.js
  • yauzl
  • Uncaught RangeError
  • uncaughtException
  • zip file
  • multipart/form-data
  • Content-Type: application/zip
  • .zip

What your security team should do

  • Inventory Node.js applications, services, serverless functions, CI jobs, and worker queues that process ZIP files from users or external sources.
  • Prioritize remediation for internet-facing upload paths and business-critical archive-processing systems.
  • Upgrade yauzl to 3.2.1 or later, including transitive dependency updates through parent packages where necessary.
  • Add defensive exception handling around ZIP parsing and metadata extraction, especially calls to entry.getLastModDate().
  • Enforce upload controls such as maximum archive size, maximum entry count, decompression limits, content-type validation, and rate limiting.
  • Run software composition analysis against lockfiles and container images to detect yauzl 3.2.0.
  • Monitor for Node.js RangeError / ERR_OUT_OF_RANGE crashes tied to ZIP processing, as these may indicate attempted exploitation.
  • If suspicious crashes are observed, preserve uploaded archive samples, request metadata, application logs, and process crash logs for forensic review.

The record

yauzl (aka Yet Another Unzip Library) version 3.2.0 for Node.js contains an off-by-one error in the NTFS extended timestamp extra field parser within the getLastModDate() function. The while loop condition checks cursor < data.length + 4 instead of cursor + 4 <= data.length, allowing readUInt16LE() to read past the buffer boundary. A remote attacker can cause a denial of service (process crash via ERR_OUT_OF_RANGE exception) by sending a crafted zip file with a malformed NTFS extra field. This affects any Node.js application that processes zip file uploads and calls entry.getLastModDate() on parsed entries. Fixed in version 3.2.1.

Affected packages

Ecosystem Package Introduced Fixed
npm yauzl 3.2.0 3.2.1
Chainguard code-server 0 4.110.1-r1
Chainguard foxx-cli 0 2.1.1-r4
Chainguard gemini-cli 0 0.33.2-r0
Chainguard kibana-7 0 7.17.29-r7
Chainguard kibana-8.17 0 8.17.10-r12
Chainguard kibana-8.17-bitnami 0 8.17.10-r12
Chainguard kibana-8.17-iamguarded 0 8.17.10-r12
Chainguard kibana-8.18 0 8.18.8-r10
Chainguard kibana-8.18-bitnami 0 8.18.8-r10
Chainguard kibana-8.18-iamguarded 0 8.18.8-r10
Chainguard kibana-8.19 0 8.19.13-r0
Chainguard kibana-8.19-bitnami 0 8.19.13-r0
Chainguard kibana-8.19-iamguarded 0 8.19.13-r0
Chainguard kibana-9.0 0 9.0.8-r13
Chainguard kibana-9.0-bitnami 0 9.0.8-r13
Chainguard kibana-9.0-iamguarded 0 9.0.8-r13
Chainguard kibana-9.1 0 9.1.10-r7
Chainguard kibana-9.1-iamguarded 0 9.1.10-r7
Chainguard kibana-9.2 0 9.2.7-r0
Chainguard kibana-9.2-iamguarded 0 9.2.6-r3
Chainguard kibana-9.3 0 9.3.2-r0
Chainguard kibana-9.3-iamguarded 0 9.3.2-r0
Chainguard langfuse-2-worker 0 2.95.12-r13
Chainguard langfuse-fips-2-worker 0 2.95.12-r16
Chainguard opensearch-dashboards-2 0 2.19.5-r1
Chainguard opensearch-dashboards-2-alerting-dashboards-plugin 0 2.19.5-r1
Chainguard opensearch-dashboards-2-anomaly-detection-dashboards-plugin 0 2.19.5-r1
Chainguard opensearch-dashboards-2-dashboards-maps 0 2.19.5-r1
Chainguard opensearch-dashboards-2-dashboards-notifications 0 2.19.5-r1
Chainguard opensearch-dashboards-2-dashboards-observability 0 2.19.5-r1
Chainguard opensearch-dashboards-2-dashboards-query-workbench 0 2.19.5-r1
Chainguard opensearch-dashboards-2-dashboards-reporting 0 2.19.5-r1
Chainguard opensearch-dashboards-2-dashboards-search-relevance 0 2.19.5-r1
Chainguard opensearch-dashboards-2-dashboards-visualizations 0 2.19.5-r1
Chainguard opensearch-dashboards-2-fips 0 2.19.5-r0
Chainguard opensearch-dashboards-2-fips-alerting-dashboards-plugin 0 2.19.5-r0
Chainguard opensearch-dashboards-2-fips-anomaly-detection-dashboards-plugin 0 2.19.5-r0
Chainguard opensearch-dashboards-2-fips-dashboards-maps 0 2.19.5-r0
Chainguard opensearch-dashboards-2-fips-dashboards-notifications 0 2.19.5-r0
Chainguard opensearch-dashboards-2-fips-dashboards-observability 0 2.19.5-r0
Chainguard opensearch-dashboards-2-fips-dashboards-query-workbench 0 2.19.5-r0
Chainguard opensearch-dashboards-2-fips-dashboards-reporting 0 2.19.5-r0
Chainguard opensearch-dashboards-2-fips-dashboards-search-relevance 0 2.19.5-r0
Chainguard opensearch-dashboards-2-fips-dashboards-visualizations 0 2.19.5-r0
Chainguard opensearch-dashboards-2-fips-index-management-dashboards-plugin 0 2.19.5-r0
Chainguard opensearch-dashboards-2-fips-ml-commons-dashboards 0 2.19.5-r0
Chainguard opensearch-dashboards-2-fips-security-analytics-dashboards-plugin 0 2.19.5-r0
Chainguard opensearch-dashboards-2-fips-security-dashboards-plugin 0 2.19.5-r0
Chainguard opensearch-dashboards-2-index-management-dashboards-plugin 0 2.19.5-r1
Chainguard opensearch-dashboards-2-ml-commons-dashboards 0 2.19.5-r1
Chainguard opensearch-dashboards-2-security-analytics-dashboards-plugin 0 2.19.5-r1
Chainguard opensearch-dashboards-2-security-dashboards-plugin 0 2.19.5-r1
Chainguard opensearch-dashboards-3 0 3.5.0-r8
Chainguard opensearch-dashboards-3-fips 0 3.5.0-r5
Chainguard renovate 0 43.77.0-r0
Wolfi code-server 0 4.110.1-r1
Wolfi opensearch-dashboards-2 0 2.19.5-r1
Wolfi opensearch-dashboards-2-alerting-dashboards-plugin 0 2.19.5-r1
Wolfi opensearch-dashboards-2-anomaly-detection-dashboards-plugin 0 2.19.5-r1
Wolfi opensearch-dashboards-2-dashboards-maps 0 2.19.5-r1
Wolfi opensearch-dashboards-2-dashboards-notifications 0 2.19.5-r1
Wolfi opensearch-dashboards-2-dashboards-observability 0 2.19.5-r1
Wolfi opensearch-dashboards-2-dashboards-query-workbench 0 2.19.5-r1
Wolfi opensearch-dashboards-2-dashboards-reporting 0 2.19.5-r1
Wolfi opensearch-dashboards-2-dashboards-search-relevance 0 2.19.5-r1
Wolfi opensearch-dashboards-2-dashboards-visualizations 0 2.19.5-r1
Wolfi opensearch-dashboards-2-index-management-dashboards-plugin 0 2.19.5-r1
Wolfi opensearch-dashboards-2-ml-commons-dashboards 0 2.19.5-r1
Wolfi opensearch-dashboards-2-security-analytics-dashboards-plugin 0 2.19.5-r1
Wolfi opensearch-dashboards-2-security-dashboards-plugin 0 2.19.5-r1
Wolfi opensearch-dashboards-3 0 3.5.0-r8
Wolfi renovate 0 43.77.0-r0

Related vulnerabilities