parse-duration has a Regex Denial of Service that results in event loop delay and out of memory
SummaryThis report finds 2 availability issues due to the regex used in the `parse-duration` npm package: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.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.PoCRefer 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:The results of this on the cloud machine that I ran this on are as follows:You can note that:0.01 MB of input was enough to cause a 1ms delay (0.92ms)Ranging from either 3 MB to 4 MB of input results in almost a full second day (728ms) and 42 ms, depending on the characters used in the text passed to the library's `parse()` functionA 200 MB of input size already causes JavaScript heap out of memory crashHowever, more interestingly, if we focus on the input string case:Even though this is merely 10 MB of size (9.97 MB) it results in an out of memory issue due to the recursive nature of the regular expression matching:To note, the issue at hand may not just be the primary regex in use but rather the reliance of the various `replace` functions in the `parse()` function which create copies of the input in memory.ImpactI agree, a 200 MB (perhaps even less if we perform more tests to find the actual threshold) is a large amount of data to send over a network and hopefully is unlikely to hit common application usage.In the case of the specialized input string case that uses a UTF-8 character it is only requires up to 10 MB of request size to cause a RangeError exception for a running Node.js application, which I think is more applicable and common to allow such input sizes for POST requests and other types.Even for the smaller payloads such as 0.01 MB which aligns with Express's default of 100kb request limit size it causes a 1ms delay. Now imagine if an application is running without proper security controls such as rate limits, and attackers send 1000s of concurrent requests which quickly turn the 1ms delay into seconds worth of delay for a running application. The 3 MB payload already shows a 0.5s delay in one request.