CVE-2026-49851: mistune Quadratic-Time DoS in parse_link_text
Sending a few thousand open-bracket characters to any app that parses user Markdown with mistune causes the CPU to spin for seconds, making denial-of-service trivially cheap.
The problem
In mistune < 3.3.0, the outer loop in InlineParser.parse() advances one character at a time whenever parse_link() returns None. Each failed attempt calls parse_link_text(), which does a fresh O(n) regex scan looking for a closing ].
With n consecutive [ characters, the outer loop runs n times and each iteration scans up to n characters, giving O(n²) total work. A 6 KB payload (6400 brackets) causes roughly 3 seconds of CPU burn per request.
Proof of concept
A working proof-of-concept for CVE-2026-49851 in mistune, with the exact payload below.
import mistune
import time
md = mistune.create_markdown()
# 6400 open brackets, no closing bracket, no valid link
s = "[" * 6400
t = time.perf_counter()
md(s)
print(time.perf_counter() - t) # ~3.2 s on a modern laptopThe root cause is a two-loop interaction: the outer parse loop never skips ahead when a link attempt fails, so it re-enters parse_link_text at every single character position. parse_link_text itself scans forward to find ], making each call O(n). The fix makes parse_link_text return the furthest position it reached even on failure, so the outer loop can jump past already-scanned input instead of advancing by one.
This is CWE-400 (Uncontrolled Resource Consumption) combined with CWE-1333 (Inefficient Regular Expression Complexity). No special privileges or authentication are needed; any endpoint that renders user-supplied Markdown is exposed.
The fix
Upgrade mistune to 3.3.0 or later (pip install --upgrade mistune). The 3.3.0 release patches parse_link_text in inline_parser.py to propagate the scan cursor forward on failure, breaking the O(n²) loop. No configuration change is needed after upgrading.
Related research
- high · 7.5CVE-2026-49477CVE-2026-49477: soupsieve Regular Expression Denial of Service (ReDoS)
- high · 7.7phantom-audio: Arbitrary File Write and Decode-Bomb DoS via Unconfined MCP Tool Paths
- high · 7.5CVE-2026-49476CVE-2026-49476: soupsieve Memory Exhaustion via Unbounded Selector List
- high · 7.5CVE-2026-49485CVE-2026-49485: org.hl7.fhir.dstu2 FHIRPathEngine ReDoS via Unprotected matches()