CVE-2026-76098
Mistune has Denial of Service — RecursionError via Excessive Emphasis Markers in Markdown
CVE-2026-76098 is a high vulnerability (CVSS 7.5) in Lepture Mistune, published August 24, 2026. No source lists public exploit code. EPSS puts the chance of exploitation in the next 30 days at 0.49%, the 42nd percentile. Fixed in mistune 3.3.3.
Mistune is a Python Markdown parser with renderers and plugins. Versions 3.3.0 through 3.3.2 are vulnerable to DoS through deeply nested tokens. HTML rendering creates deeply nested emphasis tokens from consecutive asterisk characters, and recursive rendering in HTMLRenderer.render_token() can exceed Python's recursion limit and raise RecursionError, allowing crafted Markdown to crash a parsing process. This issue is fixed in version 3.3.3
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 has Denial of Service — RecursionError via Excessive Emphasis Markers in Markdown
Mistune is a Python Markdown parser with renderers and plugins. Versions 3.3.0 through 3.3.2 are vulnerable to DoS through deeply nested tokens. HTML rendering creates deeply nested emphasis tokens from consecutive asterisk characters, and recursive rendering in HTMLRenderer.render_token() can exceed Python's recursion limit and raise RecursionError, allowing crafted Markdown to crash a parsing process. This issue is fixed in version 3.3.3
- Record
CVE-2026-76098- 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-674
- Updated
- 2026-11-02
EUVDEUVD-2026-65137
7.5
Mistune is a Python Markdown parser with renderers and plugins. Versions 3.3.0 through 3.3.2 are vulnerable to DoS through deeply nested tokens. HTML rendering creates deeply nested emphasis tokens from consecutive asterisk characters, and recursive rendering in HTMLRenderer.render_token() can exceed Python's recursion limit and raise RecursionError, allowing crafted Markdown to crash a parsing process. This issue is fixed in version 3.3.3
- Record
EUVD-2026-65137- 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-6m44-fpc8-c3rq
7.5
Mistune: Denial of Service — RecursionError via Excessive Emphasis Markers in Markdown
Summary
Mistune v3.3.2 is vulnerable to a Denial of Service (DoS) attack via uncontrolled recursion in the HTML rendering of deeply-nested emphasis tokens. By submitting Markdown containing approximately 1,000 consecutive asterisk characters, an attacker causes the Python process to crash with RecursionError.
Details
The InlineParser's _process_emphasis_delimiters() creates deeply nested <strong> tokens from consecutive emphasis markers (every 2 asterisks add one nesting level). With 1,000 consecutive asterisks, approximately 500 levels of nesting are produced. The HTMLRenderer.render_token() method (src/mistune/renderers/html.py:40-57) renders these tokens recursively: when a token has children, line 48 calls self.render_tokens(token['children'], state), entering child rendering. Each nesting level produces ~2 stack frames, so 500 levels ≈ 1,000 frames, exceeding Python's default recursion limit (sys.getrecursionlimit() = 1000). The emphasis() and strong() methods (lines 80-84) wrap recursively rendered child content in <em> and <strong> tags, perpetuating the recursion. This vulnerability affects all mistune APIs including markdown() and html().
Core vulnerable code path:
# src/mistune/renderers/html.py:40-57
def render_token(self, token: Dict[str, Any], state: BlockState) -> str:
func = self._get_method(token["type"])
attrs = token.get("attrs")
if "raw" in token:
text = token["raw"]
elif "children" in token:
text = self.render_tokens(token["children"], state)
else:
if attrs:
return func(**attrs)
else:
return func()
if attrs:
return func(text, **attrs)
else:
return func(text)
The recursive call to render_tokens() on line 48 processes nested child tokens. With 500 levels of nested emphasis/strong tokens, this recursion exceeds Python's default recursion limit of 1000, causing a RecursionError.
# src/mistune/renderers/html.py:80-84
def emphasis(self, text: str) -> str:
return "<em>" + text + "</em>"
def strong(self, text: str) -> str:
return "<strong>" + text + "</strong>"
The emphasis() and strong() methods wrap their text content (which is itself the recursively-rendered output of nested child tokens) in HTML tags, creating the chain of recursion: each call to strong() includes rendered children that themselves call strong(), etc.
POC
from mistune import html
payload = '*' * 1000
try:
result = html(payload)
print('No crash - recursion handled')
except RecursionError as e:
print(f'[VULN] RecursionError: {e} - Process would crash!')
except Exception as e:
print(f'Error: {type(e).__name__}: {e}')
<img width="1139" height="664" alt="1" src="https://github.com/user-attachments/assets/d2095b9f-0a6a-4bef-8013-cbc6946cf8f1" />
Impact
CVSS 3.1: 7.5 (High) — AV:N/AC:L/PR:N/UI:N/S:U/C:N/I:N/A:H. An attacker can crash any server process using mistune with approximately 2KB of Markdown input. In web applications, this can be triggered through user-generated content such as forum posts or comments, causing denial of service for all concurrent users sharing the same Python process. Both mistune.markdown() and mistune.html() are affected.
Remediation
- Add a maximum nesting depth limit in the emphasis parsing stage, similar to BlockParser's max_nested_level mechanism (currently at DEFAULT_MAX_NESTED_LEVEL = 20). When the limit is exceeded, treat excess emphasis markers as literal text. 2. Alternatively, refactor HTMLRenderer to use an explicit stack-based iterative approach instead of recursive calls for rendering nested tokens. 3. As a defense-in-depth measure, document the recursion risk and recommend that applications deploying mistune set a higher recursion limit or implement request-level timeouts.
- Record
GHSA-6m44-fpc8-c3rq- 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-674
- Updated
- 2026-11-02
NVD
7.5
Mistune is a Python Markdown parser with renderers and plugins. Versions 3.3.0 through 3.3.2 are vulnerable to DoS through deeply nested tokens. HTML rendering creates deeply nested emphasis tokens from consecutive asterisk characters, and recursive rendering in HTMLRenderer.render_token() can exceed Python's recursion limit and raise RecursionError, allowing crafted Markdown to crash a parsing process. This issue is fixed in version 3.3.3
- Record
CVE-2026-76098- 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-674
- Updated
- 2026-11-02
OSV
7.5
Mistune has Denial of Service — RecursionError via Excessive Emphasis Markers in Markdown
Mistune is a Python Markdown parser with renderers and plugins. Versions 3.3.0 through 3.3.2 are vulnerable to DoS through deeply nested tokens. HTML rendering creates deeply nested emphasis tokens from consecutive asterisk characters, and recursive rendering in HTMLRenderer.render_token() can exceed Python's recursion limit and raise RecursionError, allowing crafted Markdown to crash a parsing process. This issue is fixed in version 3.3.3
- Record
CVE-2026-76098- 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-674
- Updated
- 2026-11-02
OSVDEBIAN-CVE-2026-76098
7.5
Mistune is a Python Markdown parser with renderers and plugins. Versions 3.3.0 through 3.3.2 are vulnerable to DoS through deeply nested tokens. HTML rendering creates deeply nested emphasis tokens from consecutive asterisk characters, and recursive rendering in HTMLRenderer.render_token() can exceed Python's recursion limit and raise RecursionError, allowing crafted Markdown to crash a parsing process. This issue is fixed in version 3.3.3
- Record
DEBIAN-CVE-2026-76098- 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 4 moreShow less
OSVGHSA-6m44-fpc8-c3rq
7.5
Mistune: Denial of Service — RecursionError via Excessive Emphasis Markers in Markdown
Summary
Mistune v3.3.2 is vulnerable to a Denial of Service (DoS) attack via uncontrolled recursion in the HTML rendering of deeply-nested emphasis tokens. By submitting Markdown containing approximately 1,000 consecutive asterisk characters, an attacker causes the Python process to crash with RecursionError.
Details
The InlineParser's _process_emphasis_delimiters() creates deeply nested <strong> tokens from consecutive emphasis markers (every 2 asterisks add one nesting level). With 1,000 consecutive asterisks, approximately 500 levels of nesting are produced. The HTMLRenderer.render_token() method (src/mistune/renderers/html.py:40-57) renders these tokens recursively: when a token has children, line 48 calls self.render_tokens(token['children'], state), entering child rendering. Each nesting level produces ~2 stack frames, so 500 levels ≈ 1,000 frames, exceeding Python's default recursion limit (sys.getrecursionlimit() = 1000). The emphasis() and strong() methods (lines 80-84) wrap recursively rendered child content in <em> and <strong> tags, perpetuating the recursion. This vulnerability affects all mistune APIs including markdown() and html().
Core vulnerable code path:
# src/mistune/renderers/html.py:40-57
def render_token(self, token: Dict[str, Any], state: BlockState) -> str:
func = self._get_method(token["type"])
attrs = token.get("attrs")
if "raw" in token:
text = token["raw"]
elif "children" in token:
text = self.render_tokens(token["children"], state)
else:
if attrs:
return func(**attrs)
else:
return func()
if attrs:
return func(text, **attrs)
else:
return func(text)
The recursive call to render_tokens() on line 48 processes nested child tokens. With 500 levels of nested emphasis/strong tokens, this recursion exceeds Python's default recursion limit of 1000, causing a RecursionError.
# src/mistune/renderers/html.py:80-84
def emphasis(self, text: str) -> str:
return "<em>" + text + "</em>"
def strong(self, text: str) -> str:
return "<strong>" + text + "</strong>"
The emphasis() and strong() methods wrap their text content (which is itself the recursively-rendered output of nested child tokens) in HTML tags, creating the chain of recursion: each call to strong() includes rendered children that themselves call strong(), etc.
POC
from mistune import html
payload = '*' * 1000
try:
result = html(payload)
print('No crash - recursion handled')
except RecursionError as e:
print(f'[VULN] RecursionError: {e} - Process would crash!')
except Exception as e:
print(f'Error: {type(e).__name__}: {e}')
<img width="1139" height="664" alt="1" src="https://github.com/user-attachments/assets/d2095b9f-0a6a-4bef-8013-cbc6946cf8f1" />
Impact
CVSS 3.1: 7.5 (High) — AV:N/AC:L/PR:N/UI:N/S:U/C:N/I:N/A:H. An attacker can crash any server process using mistune with approximately 2KB of Markdown input. In web applications, this can be triggered through user-generated content such as forum posts or comments, causing denial of service for all concurrent users sharing the same Python process. Both mistune.markdown() and mistune.html() are affected.
Remediation
- Add a maximum nesting depth limit in the emphasis parsing stage, similar to BlockParser's max_nested_level mechanism (currently at DEFAULT_MAX_NESTED_LEVEL = 20). When the limit is exceeded, treat excess emphasis markers as literal text. 2. Alternatively, refactor HTMLRenderer to use an explicit stack-based iterative approach instead of recursive calls for rendering nested tokens. 3. As a defense-in-depth measure, document the recursion risk and recommend that applications deploying mistune set a higher recursion limit or implement request-level timeouts.
- Record
GHSA-6m44-fpc8-c3rq- 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-674
- Updated
- 2026-11-02
OSVPYSEC-2026-3863
7.5
Mistune: Denial of Service — RecursionError via Excessive Emphasis Markers in Markdown
Summary
Mistune v3.3.2 is vulnerable to a Denial of Service (DoS) attack via uncontrolled recursion in the HTML rendering of deeply-nested emphasis tokens. By submitting Markdown containing approximately 1,000 consecutive asterisk characters, an attacker causes the Python process to crash with RecursionError.
Details
The InlineParser's _process_emphasis_delimiters() creates deeply nested <strong> tokens from consecutive emphasis markers (every 2 asterisks add one nesting level). With 1,000 consecutive asterisks, approximately 500 levels of nesting are produced. The HTMLRenderer.render_token() method (src/mistune/renderers/html.py:40-57) renders these tokens recursively: when a token has children, line 48 calls self.render_tokens(token['children'], state), entering child rendering. Each nesting level produces ~2 stack frames, so 500 levels ≈ 1,000 frames, exceeding Python's default recursion limit (sys.getrecursionlimit() = 1000). The emphasis() and strong() methods (lines 80-84) wrap recursively rendered child content in <em> and <strong> tags, perpetuating the recursion. This vulnerability affects all mistune APIs including markdown() and html().
Core vulnerable code path:
# src/mistune/renderers/html.py:40-57
def render_token(self, token: Dict[str, Any], state: BlockState) -> str:
func = self._get_method(token["type"])
attrs = token.get("attrs")
if "raw" in token:
text = token["raw"]
elif "children" in token:
text = self.render_tokens(token["children"], state)
else:
if attrs:
return func(**attrs)
else:
return func()
if attrs:
return func(text, **attrs)
else:
return func(text)
The recursive call to render_tokens() on line 48 processes nested child tokens. With 500 levels of nested emphasis/strong tokens, this recursion exceeds Python's default recursion limit of 1000, causing a RecursionError.
# src/mistune/renderers/html.py:80-84
def emphasis(self, text: str) -> str:
return "<em>" + text + "</em>"
def strong(self, text: str) -> str:
return "<strong>" + text + "</strong>"
The emphasis() and strong() methods wrap their text content (which is itself the recursively-rendered output of nested child tokens) in HTML tags, creating the chain of recursion: each call to strong() includes rendered children that themselves call strong(), etc.
POC
from mistune import html
payload = '*' * 1000
try:
result = html(payload)
print('No crash - recursion handled')
except RecursionError as e:
print(f'[VULN] RecursionError: {e} - Process would crash!')
except Exception as e:
print(f'Error: {type(e).__name__}: {e}')
<img width="1139" height="664" alt="1" src="https://github.com/user-attachments/assets/d2095b9f-0a6a-4bef-8013-cbc6946cf8f1" />
Impact
CVSS 3.1: 7.5 (High) — AV:N/AC:L/PR:N/UI:N/S:U/C:N/I:N/A:H. An attacker can crash any server process using mistune with approximately 2KB of Markdown input. In web applications, this can be triggered through user-generated content such as forum posts or comments, causing denial of service for all concurrent users sharing the same Python process. Both mistune.markdown() and mistune.html() are affected.
Remediation
- Add a maximum nesting depth limit in the emphasis parsing stage, similar to BlockParser's max_nested_level mechanism (currently at DEFAULT_MAX_NESTED_LEVEL = 20). When the limit is exceeded, treat excess emphasis markers as literal text. 2. Alternatively, refactor HTMLRenderer to use an explicit stack-based iterative approach instead of recursive calls for rendering nested tokens. 3. As a defense-in-depth measure, document the recursion risk and recommend that applications deploying mistune set a higher recursion limit or implement request-level timeouts.
- Record
PYSEC-2026-3863- 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-76098
7.5
Mistune is a Python Markdown parser with renderers and plugins. Versions 3.3.0 through 3.3.2 are vulnerable to DoS through deeply nested tokens. HTML rendering creates deeply nested emphasis tokens from consecutive asterisk characters, and recursive rendering in HTMLRenderer.render_token() can exceed Python's recursion limit and raise RecursionError, allowing crafted Markdown to crash a parsing process. This issue is fixed in version 3.3.3
- Record
UBUNTU-CVE-2026-76098- 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-97956 No score
CVE-2026-76098 affecting package python-mistune for versions less than 3.3.4-1
Mistune is a Python Markdown parser with renderers and plugins. Versions 3.3.0 through 3.3.2 are vulnerable to DoS through deeply nested tokens. HTML rendering creates deeply nested emphasis tokens from consecutive asterisk characters, and recursive rendering in HTMLRenderer.render_token() can exceed Python's recursion limit and raise RecursionError, allowing crafted Markdown to crash a parsing process. This issue is fixed in version 3.3.3
- Record
AZL-97956- Updated
- 2026-11-02
Affected products
Affected packages
| Package | Affected | Fixed |
|---|---|---|
mistunePyPI |
3.3.0 up to 3.3.3 | 3.3.3 |
python-mistuneAzure Linux:3 |
before 3.3.4-1 | 3.3.4-1 |
mistuneDebian:12 |
All versions, plus listed versions 2.0.4-12.0.4-23.0.2-13.0.2-23.1.3-13.1.4-13.3.4-1 |
None known |
mistuneDebian:13 |
All versions, plus listed versions 3.1.3-13.1.4-13.3.4-1 |
None known |
mistuneDebian:14 |
All versions, plus listed versions 3.1.3-13.1.4-13.3.4-1 |
None known |
mistunePyPI |
3.3.0 up to 3.3.3, plus listed versions 3.3.13.3.2 |
3.3.3 |
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 |
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: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 |
History
| When | Changed | Sources |
|---|---|---|
| 2026-11-02 | created | CVE List, EUVD, GitHub Advisories, NVD, OSV |
References
github.com/lepture/mistune/security/advisories/GHSA-6m44-fpc8-c3rq
github.com/lepture/mistune/commit/0938fb7
nvd.nist.gov/vuln/detail/CVE-2026-76098
github.com/lepture/mistune/commit/0938fb781d0aded99de801b340ec1f8debeae5b2
github.com/lepture/mistune/releases/tag/v3.3.3
github.com/advisories/GHSA-6m44-fpc8-c3rq
Show 9 moreShow less
github.com/CVEProject/cvelistV5/tree/main/cves/2026/76xxx/CVE-2026-76098.json
security-tracker.debian.org/tracker/CVE-2026-76098
github.com/lepture/mistune
pypi.org/project/mistune
ubuntu.com/security/CVE-2026-76098
cve.org/CVERecord?id=CVE-2026-76098
github.com/cveproject/cvelistv5/tree/main/cves/2026/76xxx/cve-2026-76098.json
github.com/lepture/mistune/security/advisories/ghsa-6m44-fpc8-c3rq
nvd.nist.gov/vuln/detail/cve-2026-76098