CVE-2026-59928
Mistune block_parser: quadratic-time parsing on long lists of repeated reference-link definitions
Mistune is a Python Markdown parser with renderers and plugins. Prior to 3.3.0, a Markdown document containing many repeated or distinct reference-link definitions causes quadratic work in src/mistune/block_parser.py and the ref_links environment dictionary handling, allowing denial of service through CPU exhaustion. This issue is fixed in version 3.3.0.
Attack profile
How easy it is to exploit
- Attack vector
- Network
- Complexity
- Low
- Privileges needed
- None
- User interaction
- None
What an attacker can affect
- Confidentiality
- None
- Integrity
- None
- Availability
- High
Exploit likelihood
What each source reports
CVE List Score used
7.5
Mistune block_parser: quadratic-time parsing on long lists of repeated reference-link definitions
Mistune is a Python Markdown parser with renderers and plugins. Prior to 3.3.0, a Markdown document containing many repeated or distinct reference-link definitions causes quadratic work in src/mistune/block_parser.py and the ref_links environment dictionary handling, allowing denial of service through CPU exhaustion. This issue is fixed in version 3.3.0.
- Record
CVE-2026-59928- CVSS 3.1
- 7.5 High
CVSS:3.1/AV:N/AC:L/PR:N/UI:N/S:U/C:N/I:N/A:H - Weakness
- CWE-407, CWE-1333
- Updated
- 2026-11-02
EUVDEUVD-2026-42338
7.5
Mistune is a Python Markdown parser with renderers and plugins. Prior to 3.3.0, a Markdown document containing many repeated or distinct reference-link definitions causes quadratic work in src/mistune/block_parser.py and the ref_links environment dictionary handling, allowing denial of service through CPU exhaustion. This issue is fixed in version 3.3.0.
- Record
EUVD-2026-42338- CVSS 3.1
- 7.5 High
CVSS:3.1/AV:N/AC:L/PR:N/UI:N/S:U/C:N/I:N/A:H - Updated
- 2026-11-02
GitHub AdvisoriesGHSA-ffq3-xpv3-j92q
7.5
Mistune block_parser: quadratic-time parsing on long lists of repeated reference-link definitions
Summary
Type: Algorithmic-complexity DoS in reference-link definition handling. A markdown document with N reference-link definitions of the same key (or many distinct keys) takes O(N²) parser time. 5000 repeated [a]: u\n definitions take ~1.1 second; 10000 → ~4.5 seconds.
File: src/mistune/block_parser.py (reference-link def parsing) and the surrounding ref_links env-dictionary handling.
Root cause: every reference definition is parsed by scanning forward from each candidate position. The unikey normalisation runs per-def, the dictionary insert is per-def, and the lookup-by-label-then-iterate-defs path is linear in the number of stored defs. For input with N defs, the total work is O(N²).
Affected Code
src/mistune/block_parser.py — reference-definition rule fires on every line that matches [label]: url. For each one:
unikey(label)is called (linear scan of the label).- The def is appended to
state.env['ref_links']. - Later inline-link resolution looks up by
unikey(label)in the dict (O(1)) but the surrounding parser revisits the def list for paragraph-vs-def disambiguation.
The cumulative parse time grows as the square of the number of defs.
Why it's wrong: the parser does not amortise the def-list scan. A single forward pass with a hash-keyed dict (already in place) plus a per-line classifier should make this O(N).
Exploit Chain
- Application uses mistune to render attacker-supplied markdown. No plugins required.
- Attacker submits a 35 KB document of
[a]: u\nrepeated 5000 times followed by[click][a]. - CPU pegs for ~1.1 seconds. 10000 defs → ~4.5 s. 20000 → ~18 s. Doubling input quadruples time.
Security Impact
Attacker capability: small input → large CPU. Predictable scaling. Can be repeated.
Preconditions: application uses mistune.create_markdown() (default config) on attacker-supplied markdown. Worth noting: the ref_links dictionary persists for the lifetime of the parse, so a long document with many defs builds up memory; with N defs of attacker-chosen length, the per-def normalisation cost compounds.
Differential: PoC-verified against [email protected], default config:
import mistune, time
md = mistune.create_markdown()
for n in [1000, 2000, 5000, 10000]:
s = '[a]: u\n' * n + '[click][a]'
t = time.time()
md(s)
print(f' ref defs * {n} ({len(s)}b): {(time.time() - t) * 1000:.0f}ms')
# Output (Python 3.13, Linux, 2.5GHz CPU):
# ref defs * 1000 ( 7012b): 46ms
# ref defs * 2000 (14012b): 186ms
# ref defs * 5000 (35012b): 1121ms
# ref defs * 10000 (70012b): 4400ms
The patched build (with the surrounding parser amortised to O(N)) keeps the time linear.
Suggested Fix
Replace the per-def re-scan with a single forward pass that classifies each line into ref_def | paragraph | other once and only inserts into ref_links once per def. The dict already exists; the wasted work is in the surrounding scan loop, not in the dict operations.
A regression test asserting that md('[a]: u\n' * 50_000 + '[click][a]') completes in under 1 second would catch any regression.
- Record
GHSA-ffq3-xpv3-j92q- CVSS 3.1
- 7.5 High
CVSS:3.1/AV:N/AC:L/PR:N/UI:N/S:U/C:N/I:N/A:H - Weakness
- CWE-407, CWE-1333
- Updated
- 2026-11-02
NVD
7.5
Mistune is a Python Markdown parser with renderers and plugins. Prior to 3.3.0, a Markdown document containing many repeated or distinct reference-link definitions causes quadratic work in src/mistune/block_parser.py and the ref_links environment dictionary handling, allowing denial of service through CPU exhaustion. This issue is fixed in version 3.3.0.
- Record
CVE-2026-59928- CVSS 3.1
- 7.5 High
CVSS:3.1/AV:N/AC:L/PR:N/UI:N/S:U/C:N/I:N/A:H - Weakness
- CWE-407, CWE-1333
- Updated
- 2026-11-02
OSV
7.5
Mistune block_parser: quadratic-time parsing on long lists of repeated reference-link definitions
Mistune is a Python Markdown parser with renderers and plugins. Prior to 3.3.0, a Markdown document containing many repeated or distinct reference-link definitions causes quadratic work in src/mistune/block_parser.py and the ref_links environment dictionary handling, allowing denial of service through CPU exhaustion. This issue is fixed in version 3.3.0.
- Record
CVE-2026-59928- CVSS 3.1
- 7.5 High
CVSS:3.1/AV:N/AC:L/PR:N/UI:N/S:U/C:N/I:N/A:H - Weakness
- CWE-1333, CWE-407
- Updated
- 2026-11-02
OSVDEBIAN-CVE-2026-59928
7.5
Mistune is a Python Markdown parser with renderers and plugins. Prior to 3.3.0, a Markdown document containing many repeated or distinct reference-link definitions causes quadratic work in src/mistune/block_parser.py and the ref_links environment dictionary handling, allowing denial of service through CPU exhaustion. This issue is fixed in version 3.3.0.
- Record
DEBIAN-CVE-2026-59928- CVSS 3.1
- 7.5 High
CVSS:3.1/AV:N/AC:L/PR:N/UI:N/S:U/C:N/I:N/A:H - Updated
- 2026-11-02
Show 6 moreShow less
OSVGHSA-ffq3-xpv3-j92q
7.5
Mistune block_parser: quadratic-time parsing on long lists of repeated reference-link definitions
Summary
Type: Algorithmic-complexity DoS in reference-link definition handling. A markdown document with N reference-link definitions of the same key (or many distinct keys) takes O(N²) parser time. 5000 repeated [a]: u\n definitions take ~1.1 second; 10000 → ~4.5 seconds.
File: src/mistune/block_parser.py (reference-link def parsing) and the surrounding ref_links env-dictionary handling.
Root cause: every reference definition is parsed by scanning forward from each candidate position. The unikey normalisation runs per-def, the dictionary insert is per-def, and the lookup-by-label-then-iterate-defs path is linear in the number of stored defs. For input with N defs, the total work is O(N²).
Affected Code
src/mistune/block_parser.py — reference-definition rule fires on every line that matches [label]: url. For each one:
unikey(label)is called (linear scan of the label).- The def is appended to
state.env['ref_links']. - Later inline-link resolution looks up by
unikey(label)in the dict (O(1)) but the surrounding parser revisits the def list for paragraph-vs-def disambiguation.
The cumulative parse time grows as the square of the number of defs.
Why it's wrong: the parser does not amortise the def-list scan. A single forward pass with a hash-keyed dict (already in place) plus a per-line classifier should make this O(N).
Exploit Chain
- Application uses mistune to render attacker-supplied markdown. No plugins required.
- Attacker submits a 35 KB document of
[a]: u\nrepeated 5000 times followed by[click][a]. - CPU pegs for ~1.1 seconds. 10000 defs → ~4.5 s. 20000 → ~18 s. Doubling input quadruples time.
Security Impact
Attacker capability: small input → large CPU. Predictable scaling. Can be repeated.
Preconditions: application uses mistune.create_markdown() (default config) on attacker-supplied markdown. Worth noting: the ref_links dictionary persists for the lifetime of the parse, so a long document with many defs builds up memory; with N defs of attacker-chosen length, the per-def normalisation cost compounds.
Differential: PoC-verified against [email protected], default config:
import mistune, time
md = mistune.create_markdown()
for n in [1000, 2000, 5000, 10000]:
s = '[a]: u\n' * n + '[click][a]'
t = time.time()
md(s)
print(f' ref defs * {n} ({len(s)}b): {(time.time() - t) * 1000:.0f}ms')
# Output (Python 3.13, Linux, 2.5GHz CPU):
# ref defs * 1000 ( 7012b): 46ms
# ref defs * 2000 (14012b): 186ms
# ref defs * 5000 (35012b): 1121ms
# ref defs * 10000 (70012b): 4400ms
The patched build (with the surrounding parser amortised to O(N)) keeps the time linear.
Suggested Fix
Replace the per-def re-scan with a single forward pass that classifies each line into ref_def | paragraph | other once and only inserts into ref_links once per def. The dict already exists; the wasted work is in the surrounding scan loop, not in the dict operations.
A regression test asserting that md('[a]: u\n' * 50_000 + '[click][a]') completes in under 1 second would catch any regression.
- Record
GHSA-ffq3-xpv3-j92q- CVSS 3.1
- 7.5 High
CVSS:3.1/AV:N/AC:L/PR:N/UI:N/S:U/C:N/I:N/A:H - Weakness
- CWE-1333, CWE-407
- Updated
- 2026-11-02
OSVPYSEC-2026-2216
7.5
Mistune is a Python Markdown parser with renderers and plugins. Prior to 3.3.0, a Markdown document containing many repeated or distinct reference-link definitions causes quadratic work in src/mistune/block_parser.py and the ref_links environment dictionary handling, allowing denial of service through CPU exhaustion. This issue is fixed in version 3.3.0.
- Record
PYSEC-2026-2216- CVSS 3.1
- 7.5 High
CVSS:3.1/AV:N/AC:L/PR:N/UI:N/S:U/C:N/I:N/A:H - Updated
- 2026-11-02
OSVUBUNTU-CVE-2026-59928
7.5
Mistune is a Python Markdown parser with renderers and plugins. Prior to 3.3.0, a Markdown document containing many repeated or distinct reference-link definitions causes quadratic work in src/mistune/block_parser.py and the ref_links environment dictionary handling, allowing denial of service through CPU exhaustion. This issue is fixed in version 3.3.0.
- Record
UBUNTU-CVE-2026-59928- CVSS 3.1
- 7.5 High
CVSS:3.1/AV:N/AC:L/PR:N/UI:N/S:U/C:N/I:N/A:H - Updated
- 2026-11-02
OSVAZL-92211 No score
CVE-2026-59928 affecting package python-mistune for versions less than 3.3.0-1
Mistune is a Python Markdown parser with renderers and plugins. Prior to 3.3.0, a Markdown document containing many repeated or distinct reference-link definitions causes quadratic work in src/mistune/block_parser.py and the ref_links environment dictionary handling, allowing denial of service through CPU exhaustion. This issue is fixed in version 3.3.0.
- Record
AZL-92211- Updated
- 2026-11-05
OSVopenSUSE-SU-2026:21339-1 No score
Security update for python-mistune
This update for python-mistune fixes the following issues
- CVE-2026-59922: quadratic-time parsing on long runs of some markers in
formatting.pycan lead to DoS (bsc#1271117). - CVE-2026-59923:
HTMLRenderer.safe_url()does not block percent-encoded javascript URIs and allows for XSS (bsc#1271119). - CVE-2026-59924: improper processing of user-supplied include paths in
Include.parse()can lead to path traversal and arbitrary file reads (bsc#1271121). - CVE-2026-59925: quadratic-time parsing on long runs of some emphasis pairs in
inline_parsercan lead to DoS (bsc#1271125). - CVE-2026-59926: improper escaping in
render_admonition()can lead to atribute injection and XSS (bsc#1271127). - CVE-2026-59927: uncontrolled recursion when processing two markdown files that include each other can lead to a DoS (bsc#1271128).
- CVE-2026-59928: quadratic-time parsing on long lists of repeated reference-link definitions in
block_parsercan lead to DoS (bsc#1271131). - CVE-2026-59929: HARMFUL_PROTOCOLS list misses legacy and chained schemes and allow arbitrary script execution in user agents (bsc#1271132).
- CVE-2026-59930: the
tocplugin andTableOfContentsdirective generate heading IDs with predictable values and allow for collisions with attacker-controlledid="toc_N"content (bsc#1271082).
- Record
openSUSE-SU-2026:21339-1- Updated
- 2026-11-02
OSVSUSE-SU-2026:22655-1 No score
Security update for python-mistune
This update for python-mistune fixes the following issues
- CVE-2026-59922: quadratic-time parsing on long runs of some markers in
formatting.pycan lead to DoS (bsc#1271117). - CVE-2026-59923:
HTMLRenderer.safe_url()does not block percent-encoded javascript URIs and allows for XSS (bsc#1271119). - CVE-2026-59924: improper processing of user-supplied include paths in
Include.parse()can lead to path traversal and arbitrary file reads (bsc#1271121). - CVE-2026-59925: quadratic-time parsing on long runs of some emphasis pairs in
inline_parsercan lead to DoS (bsc#1271125). - CVE-2026-59926: improper escaping in
render_admonition()can lead to atribute injection and XSS (bsc#1271127). - CVE-2026-59927: uncontrolled recursion when processing two markdown files that include each other can lead to a DoS (bsc#1271128).
- CVE-2026-59928: quadratic-time parsing on long lists of repeated reference-link definitions in
block_parsercan lead to DoS (bsc#1271131). - CVE-2026-59929: HARMFUL_PROTOCOLS list misses legacy and chained schemes and allow arbitrary script execution in user agents (bsc#1271132).
- CVE-2026-59930: the
tocplugin andTableOfContentsdirective generate heading IDs with predictable values and allow for collisions with attacker-controlledid="toc_N"content (bsc#1271082).
- Record
SUSE-SU-2026:22655-1- Updated
- 2026-11-02
Affected products
Affected packages
| Package | Affected | Fixed |
|---|---|---|
mistunePyPI |
before 3.3.0 | 3.3.0 |
python-mistuneAzure Linux:3 |
before 3.3.0-1 | 3.3.0-1 |
mistuneDebian:13 |
All versions, plus listed versions 3.1.3-13.1.4-13.3.4-13.4.0-1 |
None known |
mistuneDebian:14 |
All versions, plus listed versions 3.1.3-13.1.4-13.3.4-13.4.0-1 |
None known |
mistunePyPI |
before 3.3.0, plus listed versions 0.1.00.2.00.3.00.3.10.4 Show 45 moreShow less0.4.10.50.5.10.60.70.7.10.7.20.7.30.7.40.80.8.10.8.20.8.30.8.42.0.02.0.0a12.0.0a22.0.0a32.0.0a42.0.0a52.0.0a62.0.0rc12.0.12.0.22.0.32.0.42.0.52.1.03.0.03.0.0a13.0.0a23.0.0a33.0.0rc13.0.0rc23.0.0rc33.0.0rc43.0.0rc53.0.13.0.23.1.03.1.13.1.23.1.33.1.43.2.0 |
3.3.0 |
python-mistuneSUSE:Linux Enterprise Server 16.0 From an advisory covering 10 CVEs |
before 3.1.3-160000.5.1 | 3.1.3-160000.5.1 |
python-mistuneSUSE:Linux Enterprise Server for SAP applications 16.0 From an advisory covering 10 CVEs |
before 3.1.3-160000.5.1 | 3.1.3-160000.5.1 |
mistuneUbuntu:16.04:LTS |
All versions, plus listed versions 0.6-20.7.1-1 |
None known |
mistuneUbuntu:18.04:LTS |
All versions, plus listed versions 0.7.4-10.8-10.8.1-10.8.3-2 |
None known |
mistuneUbuntu:20.04:LTS |
All versions, plus listed versions 0.8.4-10.8.4-2 |
None known |
Show 6 moreShow less
| Package | Affected | Fixed |
|---|---|---|
mistuneUbuntu:22.04:LTS |
All versions, plus listed versions 0.8.4-40.8.4-52.0.0-1+really0.8.4-1 |
None known |
mistuneUbuntu:24.04:LTS |
All versions, plus listed versions 2.0.4-23.0.2-1 |
None known |
mistuneUbuntu:25.10 |
All versions, plus listed versions 3.0.2-23.1.3-1 |
None known |
mistuneUbuntu:26.10 |
All versions, plus listed versions 3.1.4-1 |
None known |
mistuneUbuntu:26.04:LTS |
All versions, plus listed versions 3.1.3-13.1.4-1 |
None known |
python-mistuneopenSUSE:Leap 16.0 From an advisory covering 10 CVEs |
before 3.1.3-160000.5.1 | 3.1.3-160000.5.1 |
History
| Recorded | Changed | Sources |
|---|---|---|
| affected | ||
| facts | OSV | |
| first indexed | CVE List, EUVD, GitHub Advisories, NVD, OSV |
Dates are when Every CVE recorded each change. Upstream dates may differ.
In short
CVE-2026-59928 is a high vulnerability (CVSS 7.5) in Lepture Mistune, published July 8, 2026. No source lists public exploit code. EPSS puts the chance of exploitation in the next 30 days at 0.65%, the 51st percentile. Fixed in mistune 3.3.0.
References
github.com/lepture/mistune/security/advisories/GHSA-ffq3-xpv3-j92q
github.com/lepture/mistune/commit/2b04d7ba341c16ac78fe82d3076bdd5c3de87c69
github.com/lepture/mistune/releases/tag/v3.3.0
nvd.nist.gov/vuln/detail/CVE-2026-59928
github.com/pypa/advisory-database/tree/main/vulns/mistune/PYSEC-2026-2216.yaml
github.com/advisories/GHSA-ffq3-xpv3-j92q
Show 25 moreShow less
github.com/CVEProject/cvelistV5/tree/main/cves/2026/59xxx/CVE-2026-59928.json
security-tracker.debian.org/tracker/CVE-2026-59928
github.com/lepture/mistune
suse.com/support/update/announcement/2026/suse-su-202622655-1
bugzilla.suse.com/1271082
bugzilla.suse.com/1271117
bugzilla.suse.com/1271119
bugzilla.suse.com/1271121
bugzilla.suse.com/1271125
bugzilla.suse.com/1271127
bugzilla.suse.com/1271128
bugzilla.suse.com/1271131
bugzilla.suse.com/1271132
suse.com/security/cve/CVE-2026-44896
suse.com/security/cve/CVE-2026-59922
suse.com/security/cve/CVE-2026-59923
suse.com/security/cve/CVE-2026-59924
suse.com/security/cve/CVE-2026-59925
suse.com/security/cve/CVE-2026-59926
suse.com/security/cve/CVE-2026-59927
suse.com/security/cve/CVE-2026-59928
suse.com/security/cve/CVE-2026-59929
suse.com/security/cve/CVE-2026-59930
ubuntu.com/security/CVE-2026-59928
cve.org/CVERecord?id=CVE-2026-59928
Left out here: 1 version. The JSON record has them.