Algorithmic Complexity DoS in @chenglou/pretext
A denial-of-service vulnerability exists in the `isRepeatedSingleCharRun()` function of the `@chenglou/pretext` npm package (versions 0.0.4 and earlier), which exhibits O(n²) algorithmic complexity when processing input consisting of repeated identical punctuation characters, leading to main thread blocking and DoS.
The @chenglou/pretext npm package, version 0.0.4 and earlier, is vulnerable to a denial-of-service attack due to inefficient algorithmic complexity in the isRepeatedSingleCharRun() function. This function, located in src/analysis.ts, rescans the entire accumulated segment on every merge iteration during text analysis. This results in O(n²) total work for input consisting of repeated identical punctuation characters. An attacker who controls text passed to the prepare() function can exploit this vulnerability to block the main thread for a significant amount of time. For example, an 80KB input string consisting of repeated parenthesis characters (e.g., "(".repeat(80_000)) can block the main thread for approximately 20 seconds on Node.js v24.12.0 running on Windows x64. This issue was identified in commit 9364741d3562fcc65aacc50953e867a5cb9fdb23 (v0.0.4).
Attack Chain
- An attacker crafts a text string containing a large number of repeated, identical punctuation characters such as
(,[,{,#,@,!,%,^,~,<, or>. - The attacker submits the crafted text string to an application that uses the
@chenglou/pretextlibrary. The text could be sent as a message in a chat application, submitted in a comment form, or used in server-side rendering. - The application's code calls the
prepare()function from the@chenglou/pretextlibrary to perform layout measurement on the attacker-controlled text. This happens inlayout.tsat line 472. - The
prepare()function internally callsprepareInternal()inlayout.ts(line 424), which then invokesanalyzeText()at line 430. analyzeText()calls thebuildMergedSegmentation()function (analysis.ts:1013 -> analysis.ts:795) to process the text. This function usesIntl.Segmenterto break the text into segments.- For each segment identified by
Intl.Segmenter, thebuildMergedSegmentation()function iterates through the segments, checking if consecutive non-word-like segments consist of the same single character. When it finds matching segments, it merges them. - During the merge process, the
isRepeatedSingleCharRun()function is called (analysis.ts:857 -> analysis.ts:285) to verify that all characters in the accumulated segment match the character being merged. - The
isRepeatedSingleCharRun()function iterates over the entire accumulated string (O(n) operation) for each merge, resulting in O(n²) complexity for large inputs. This causes the main thread to block. The final objective is to cause denial of service on the client or server processing the text.
Impact
This vulnerability allows an attacker to cause a denial-of-service (DoS) condition.
Specifically, chat/messaging applications, comment/form systems, or server-side rendering processes that use @chenglou/pretext can be targeted. A single crafted message or input (e.g., 80KB of repeated parenthesis characters) can block the main thread for approximately 20 seconds. In server-side rendering scenarios (Node.js/Bun), a single malicious request can consume excessive CPU time (20+ seconds per 80KB of payload). This can lead to a complete outage of the affected service.
Recommendation
- Limit the length of text passed to the
prepare()function to mitigate the impact of this vulnerability before a patch is available. - Monitor CPU usage for processes utilizing the
@chenglou/pretextlibrary for unusually long execution times that could indicate exploitation of this vulnerability. - Deploy the Sigma rule that detects potential exploitation attempts based on excessive process execution time.
- Upgrade to a patched version of
@chenglou/pretextonce it becomes available.
Detection coverage 2
Detect Long Running Node.js Process
mediumDetects Node.js processes running for unusually long durations, which might indicate exploitation of the algorithmic complexity vulnerability in @chenglou/pretext.
Detect Long Running Node.js Process Linux
mediumDetects Node.js processes running for unusually long durations, which might indicate exploitation of the algorithmic complexity vulnerability in @chenglou/pretext on Linux
Detection queries are available on the platform. Get full rules →