Skip to main content
CVE Vulnerability Database
Vulnerability Database/CVE-2026-24001

CVE-2026-24001: jsdiff Library DoS Vulnerability

CVE-2026-24001 is a denial-of-service vulnerability in the jsdiff JavaScript library that causes infinite loops when parsing malformed patches. This article covers technical details, affected versions, impact, and mitigation.

Published:

CVE-2026-24001 Overview

CVE-2026-24001 is a Denial of Service vulnerability in jsdiff, a popular JavaScript text differencing implementation. The vulnerability allows attackers to trigger an infinite loop in the parsePatch method by crafting malicious patch files containing specific line break characters (\r, \\u2028, or \\u2029) in filename headers. This leads to unbounded memory consumption until the process crashes.

Critical Impact

Applications using jsdiff to parse user-provided patches are vulnerable to denial-of-service attacks. The vulnerability requires no large payload to exploit, making input size limits ineffective as protection.

Affected Products

  • jsdiff versions prior to 8.0.3
  • jsdiff versions prior to 5.2.2
  • jsdiff versions prior to 4.0.4

Discovery Timeline

  • 2026-01-22 - CVE CVE-2026-24001 published to NVD
  • 2026-01-22 - Last updated in NVD database

Technical Details for CVE-2026-24001

Vulnerability Analysis

The vulnerability exists in the parsePatch function within jsdiff's patch parsing module. When processing patch files, the function's regular expression for parsing file headers (--- and +++ lines) fails to properly handle certain Unicode line break characters. Specifically, the presence of carriage return (\r), line separator (\\u2028), or paragraph separator (\\u2029) characters in filename headers causes the parsing logic to enter an infinite loop.

A secondary, related vulnerability manifests as a Regular Expression Denial of Service (ReDoS) when these same characters appear in the patch header (also known as "leading garbage"). In this case, a maliciously-crafted patch header of length n can cause parsePatch to take O(n³) time to process, enabling algorithmic complexity attacks.

The applyPatch method is also affected when called with a string representation of a patch, as it internally uses parsePatch to process the input.

Root Cause

The root cause is improper input validation in the file header parsing regular expression. The original regex pattern (/^(---|\\+\\+\\+)\\s+(.*)\\r?$/) attempted to handle carriage returns but failed to account for Unicode line terminators. This allowed specially crafted input to bypass the expected parsing flow, causing the parser to loop indefinitely without advancing through the input.

Attack Vector

The attack is network-based and requires no authentication or user interaction. An attacker can exploit this vulnerability by:

  1. Providing a maliciously crafted patch file to any application that uses jsdiff's parsePatch or applyPatch methods
  2. Injecting malicious characters into filenames if the application allows user control over filenames used in diff operations
  3. Submitting crafted patches through web interfaces, APIs, or any input mechanism that feeds into jsdiff
typescript
// Security patch in src/patch/parse.ts
// Source: https://github.com/kpdecker/jsdiff/commit/15a1585230748c8ae6f8274c202e0c87309142f5

   // Parses the --- and +++ headers, if none are found, no lines
   // are consumed.
   function parseFileHeader(index: Partial<StructuredPatch>) {
-    const fileHeader = (/^(---|\\+\\+\\+)\\s+(.*)\\r?$/).exec(diffstr[i]);
-    if (fileHeader) {
-      const data = fileHeader[2].split('\\t', 2),
+    const fileHeaderMatch = (/^(---|\\+\\+\\+)\\s+/).exec(diffstr[i]);
+    if (fileHeaderMatch) {
+      const prefix = fileHeaderMatch[1],
+            data = diffstr[i].substring(3).trim().split('\\t', 2),
             header = (data[1] || '').trim();
       let fileName = data[0].replace(/\\\\/g, '\\');
-      if ((/^".*"$/).test(fileName)) {
+      if (fileName.startsWith('"') && fileName.endsWith('"')) {
         fileName = fileName.substr(1, fileName.length - 2);
       }
-      if (fileHeader[1] === '---') {
+      if (prefix === '---') {
         index.oldFileName = fileName;
         index.oldHeader = header;
       } else {

Detection Methods for CVE-2026-24001

Indicators of Compromise

  • Abnormal memory consumption in Node.js or JavaScript runtime processes handling patch operations
  • Application crashes or out-of-memory errors in services that process user-submitted patches
  • Unusual CPU spikes during patch parsing operations
  • Process hangs without visible network or I/O activity when handling diff operations

Detection Strategies

  • Monitor memory usage patterns in applications that utilize jsdiff for patch processing
  • Implement logging around parsePatch and applyPatch calls to detect processing delays exceeding normal thresholds
  • Use application performance monitoring (APM) tools to detect infinite loop patterns characterized by CPU usage without progress
  • Audit dependency manifests for vulnerable jsdiff versions using npm audit or similar tools

Monitoring Recommendations

  • Set up alerts for memory threshold breaches in services using jsdiff
  • Implement request timeout monitoring for endpoints that process patch data
  • Deploy resource quotas and circuit breakers for patch processing services
  • Monitor for repeated crashes or restarts of affected services

How to Mitigate CVE-2026-24001

Immediate Actions Required

  • Update jsdiff to version 8.0.3, 5.2.2, or 4.0.4 depending on your major version branch
  • Audit applications to identify all code paths that call parsePatch or applyPatch with user-controlled input
  • Implement input sanitization to reject patches containing \r, \\u2028, or \\u2029 characters before passing to jsdiff
  • Deploy resource limits (memory caps, timeouts) around patch processing operations

Patch Information

The vulnerability has been fixed in jsdiff versions 8.0.3, 5.2.2, and 4.0.4. The fix modifies the file header parsing logic to avoid the problematic regular expression pattern and properly handle line termination. For detailed information, see the GitHub Security Advisory, GitHub Pull Request #649, and the commit containing the fix.

Workarounds

  • Filter input patches to remove or reject any containing carriage return (\r), line separator (\\u2028), or paragraph separator (\\u2029) characters
  • Implement a pre-validation function that scans patch content before processing
  • Run jsdiff operations in isolated worker threads with strict memory and time limits
  • Consider using a web worker or separate process with resource constraints for untrusted patch parsing
bash
# Configuration example
# Pre-validate patch files before processing with jsdiff
# This regex check can be implemented before calling parsePatch

# In Node.js, sanitize input before parsing:
# if (/[\r\\u2028\\u2029]/.test(patchString)) {
#   throw new Error('Invalid characters in patch file');
# }

# Update jsdiff to patched version
npm update diff@8.0.3
# or for older major versions:
npm update diff@5.2.2
npm update diff@4.0.4

Disclaimer: This content was generated using AI. While we strive for accuracy, please verify critical information with official sources.

Default Legacy - Prefooter | Experience the World’s Most Advanced Cybersecurity Platform

Experience the Most Advanced Cybersecurity Platform

See how the world’s most intelligent, autonomous cybersecurity platform can protect your organization today and into the future.