VYPR
High severity7.5NVD Advisory· Published Feb 12, 2025· Updated Apr 15, 2026

CVE-2025-25283

CVE-2025-25283

Description

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.

Affected packages

Versions sourced from the GitHub Security Advisory.

PackageAffected versionsPatched versions
parse-durationnpm
< 2.1.32.1.3

Patches

2
9e88421bfd41

Merge pull request #61 from jkroso/fix-regex

https://github.com/jkroso/parse-durationDmitry Iv.Feb 11, 2025via ghsa
4 files changed · +19 19
  • index.d.ts+1 1 modified
    @@ -22,7 +22,7 @@ declare module './locale/*.js' {
     declare const durationRE: RegExp;
     
     declare namespace parse {
    -  const unit: Units;
    +  let unit: Units;
     }
     
     /**
    
  • index.js+10 11 modified
    @@ -1,37 +1,36 @@
     import en from './locale/en.js'
     
    -const durationRE = /(-?(?:\d+\.?\d*|\d*\.?\d+)(?:e[-+]?\d+)?)\s*([\p{L}]*)/uig
    +const durationRE = /((?:\d{1,16}(?:\.\d{1,16})?|\.\d{1,16})(?:[eE][-+]?\d{1,4})?)\s?([\p{L}]{0,14})/gu
     
     parse.unit = en
     
     /**
      * convert `str` to ms
      *
    - * @param {String} str
    - * @param {String} format
    - * @return {Number}
    + * @param {string} str
    + * @param {string} format
    + * @return {number}
      */
     export default function parse(str = '', format = 'ms') {
       let result = null, prevUnits
     
    -  (str + '')
    -    .replace(/(\d)[_ ](\d)/g, '$1$2')     // ignore placeholders
    -    .replaceAll(parse.unit.group, '')     // remove group separator
    -    .replaceAll(parse.unit.decimal, '.')  // normalize decimal separator
    +  String(str)
    +    .replace(new RegExp(`(\\d)[${parse.unit.placeholder}${parse.unit.group}](\\d)`, 'g'), '$1$2')  // clean up group separators / placeholders
    +    .replace(parse.unit.decimal, '.') // normalize decimal separator
         .replace(durationRE, (_, n, units) => {
         // if no units, find next smallest units or fall back to format value
         // eg. 1h30 -> 1h30m
         if (!units) {
           if (prevUnits) {
    -        for (var u in parse.unit) if (parse.unit[u] < prevUnits) { units = u; break }
    +        for (const u in parse.unit) if (parse.unit[u] < prevUnits) { units = u; break }
           }
           else units = format
         }
         else units = units.toLowerCase()
     
    -    units = parse.unit[units] || parse.unit[units.replace(/s$/, '')]
    +    prevUnits = units = parse.unit[units] || parse.unit[units.replace(/s$/, '')]
     
    -    if (units) result = (result || 0) + Math.abs(parseFloat(n, 10)) * units, prevUnits = units
    +    if (units) result = (result || 0) + n * units
       })
     
       return result && ((result / (parse.unit[format] || 1)) * (str[0] === '-' ? -1 : 1))
    
  • locale/en.js+1 0 modified
    @@ -14,5 +14,6 @@ unit.nanosecond = unit.nanosec = unit.ns = 1e-6
     
     unit.group = ','
     unit.decimal = '.'
    +unit.placeholder = ' _'
     
     export default unit
    
  • test.js+7 7 modified
    @@ -167,15 +167,15 @@ t('locales', t => {
     t('locale separators', t => {
     	parse.unit = en
     	t.equal(parse('3.14 seconds'), 3140)
    -	t.equal(parse('"1,23,456.789 seconds'), 123456789)
    -	t.equal(parse('"1,23,456.789s'), 123456789)
    -	t.equal(parse('"30,000.65 seconds'), 30000650)
    +	t.equal(parse('1,23,456.789 seconds'), 123456789)
    +	t.equal(parse('1,23,456.789s'), 123456789)
    +	t.equal(parse('30,000.65 seconds'), 30000650)
     
     	parse.unit = de
     	t.equal(parse('3,14 seconds'), 3140)
    -	t.equal(parse('"123.456,789 seconds'), 123456789)
    -	t.equal(parse('"30.000,65 seconds'), 30000650)
    -	t.equal(parse('"30 000,65 seconds'), 30000650)
    -	t.equal(parse('"30_000,65 seconds'), 30000650)
    +	t.equal(parse('123.456,789 seconds'), 123456789)
    +	t.equal(parse('30.000,65 seconds'), 30000650)
    +	t.equal(parse('30 000,65 seconds'), 30000650)
    +	t.equal(parse('30_000,65 seconds'), 30000650)
     	t.end()
     })
    

Vulnerability mechanics

Generated by null/stub on May 9, 2026. Inputs: CWE entries + fix-commit diffs from this CVE's patches. Citations validated against bundle.

References

5

News mentions

0

No linked articles in our index yet.