CVE-2026-33079: Mistune Denial of Service Vulnerability
HIGHCVE-2026-33079 is a HIGH denial of service vulnerability (CWE-1333: Inefficient Regular Expression Complexity) affecting Mistune libraries in the PyPI ecosystem. The issue involves mistune has a redos in link_title_re that allows denial of service via crafted markdown input. Remediation is available by upgrading affected packages to version 3.2.1.
CVE-2026-33079 at a Glance
How to Fix CVE-2026-33079
To remediate this vulnerability, upgrade all affected Mistune dependencies to a patched release. Both direct and transitive dependencies should be checked, as frameworks or security libraries may pull in vulnerable versions transitively.
pip install mistune>=3.2.1
Run the following command in your project directory to verify that all resolved dependencies use the patched release:
pip show mistune
How to Check if You Are Affected
To determine whether your Python environment is affected by CVE-2026-33079, inspect your installed packages using pip:
pip show mistune
Analyze the terminal output to locate any version of Mistune in your dependency tree. If any resolved version matches the vulnerable ranges listed in the table below (for example, versions earlier than 3.2.1), your application is affected.
Note: The pip show mistune command checks currently installed packages in your active Python environment.
Technical Details
Vulnerability Mechanism & Technical Analysis
This vulnerability is classified under CWE-1333: Inefficient Regular Expression Complexity, where the product uses a regular expression with a worst-case computational complexity that is inefficient and possibly exponential. In Mistune, software state validation or input boundaries are circumvented during processing. Review the official source advisory statement below for specific affected components, classes, and reproduction details.
Source Advisory Statement
CVE-2026-33079 Affected Mistune Versions
1 component(s)| Product / Package | Ecosystem | Affected Versions | Fixed Version |
|---|---|---|---|
|
mistune
|
PyPI |
≥ 3.0.0a1
< 3.2.1
|
3.2.1
|
References
Frequently Asked Questions
What is CVE-2026-33079?
Which Mistune versions are affected?
What version fixes CVE-2026-33079?
Is mistune affected?
What CWE is associated with CVE-2026-33079?
How can I check PyPI dependencies for CVE-2026-33079?
Machine-readable OSV JSON
OSV v1.5 Schema
{
"schema_version" : "1.4.0",
"id" : "GHSA-8mp2-v27r-99xp",
"modified" : "2026-05-06T19:35:51Z",
"published" : "2026-05-06T16:52:43Z",
"aliases" : [ "CVE-2026-33079" ],
"summary" : "Mistune has a ReDoS in LINK_TITLE_RE that allows denial of service via crafted Markdown input",
"details" : "### Summary\n\nA ReDoS (Regular Expression Denial of Service) vulnerability in `LINK_TITLE_RE` allows an attacker who can supply Markdown for parsing to cause denial of service. A crafted 58-byte Markdown document blocks the parser for approximately 6 seconds (measured on Apple M2, Python 3.14.3), with exponential growth per additional byte pair.\n\n### Details\n\nThe vulnerable regex is defined in [`src/mistune/helpers.py#L20-L25`](https://github.com/lepture/mistune/blob/df23edd60b43b639d2e6760ef9dd3d618aa11c21/src/mistune/helpers.py#L20-L25):\n\n```python\nLINK_TITLE_RE = re.compile(\n r\"[ \\t\\n]+(\"\n r'\"(?:\\\\' + PUNCTUATION + r'|[^\"\\x00])*\"|' # \"title\"\n r\"'(?:\\\\\" + PUNCTUATION + r\"|[^'\\x00])*'\" # 'title'\n r\")\"\n)\n```\n\nThe double-quote branch compiles to `\"(?:\\\\[PUNCTUATION]|[^\"\\x00])*\"`. The two alternatives inside `(A|B)*` overlap: a backslash followed by a punctuation character (e.g. `\\!`) can be matched by **either** branch — as a 2-character escaped-punctuation sequence `\\\\!`, or as two individual `[^\"\\x00]` characters (`\\` then `!`). The same ambiguity exists in the single-quoted title branch.\n\nWhen the input contains repeated `\\!` pairs with no closing `\"`, the regex engine exhaustively backtracks through all 2^N combinations, resulting in **exponential O(2^N) time complexity**.\n\nThis is reachable through normal Markdown parsing via two code paths:\n1. **Inline links**: `[text](url \"PAYLOAD)` → [`parse_link()`](https://github.com/lepture/mistune/blob/df23edd60b43b639d2e6760ef9dd3d618aa11c21/src/mistune/helpers.py#L178) → [`parse_link_title()`](https://github.com/lepture/mistune/blob/df23edd60b43b639d2e6760ef9dd3d618aa11c21/src/mistune/helpers.py#L169)\n2. **Block link reference definitions**: `[label]: url \"PAYLOAD` → [`BlockParser.parse_ref_link()`](https://github.com/lepture/mistune/blob/df23edd60b43b639d2e6760ef9dd3d618aa11c21/src/mistune/block_parser.py#L220) → [`parse_link_title()`](https://github.com/lepture/mistune/blob/df23edd60b43b639d2e6760ef9dd3d618aa11c21/src/mistune/helpers.py#L169) at [block_parser.py#L259](https://github.com/lepture/mistune/blob/df23edd60b43b639d2e6760ef9dd3d618aa11c21/src/mistune/block_parser.py#L259)\n\n### PoC\n\n```python\nimport mistune\nimport time\n\nmd = mistune.create_markdown()\n\n# Test with increasing N (number of \\! pairs)\nfor n in [15, 18, 20, 22, 25]:\n payload = '[x](y \"' + '\\\\!' * n + ')'\n start = time.time()\n md(payload)\n elapsed = time.time() - start\n print(f\"N={n:2d} len={len(payload):3d} bytes time={elapsed:.3f}s\")\n```\n\nOutput (Apple M2, Python 3.14.3, mistune 3.2.0):\n\n```\nN=15 len= 38 bytes time=0.007s\nN=18 len= 44 bytes time=0.044s\nN=20 len= 48 bytes time=0.178s\nN=22 len= 52 bytes time=0.740s\nN=25 len= 58 bytes time=5.922s\n```\n\nEach increment of N roughly doubles the execution time (consistent with O(2^N)).\n\nThe same attack works via block link reference definitions:\n\n```python\npayload = '[l]: u \"' + '\\\\!' * 25 # 58 bytes, ~6 seconds\nmd(payload)\n```\n\n### Impact\n\nThis is a denial of service vulnerability. Any application or service that parses user-supplied Markdown using mistune can be made unresponsive by an attacker submitting a small crafted input (under 100 bytes).\n\nAffected use cases include:\n- Web applications with Markdown-enabled input fields (comments, posts, descriptions)\n- Documentation systems that accept user contributions\n- API endpoints that process Markdown\n- Jupyter tooling such as nbconvert that relies on mistune for rendering\n\n### Suggested Fix\n\nExclude the backslash character from the catch-all character class to eliminate the alternation overlap:\n\n```python\n# Before (vulnerable):\nr'\"(?:\\\\' + PUNCTUATION + r'|[^\"\\x00])*\"'\nr\"'(?:\\\\\" + PUNCTUATION + r\"|[^'\\x00])*'\"\n\n# After (fixed):\nr'\"(?:\\\\' + PUNCTUATION + r'|[^\"\\\\\\x00])*\"'\nr\"'(?:\\\\\" + PUNCTUATION + r\"|[^'\\\\\\x00])*'\"\n```\n\nThis ensures a backslash can only be consumed by the escaped-punctuation branch, eliminating the ambiguity in both the double-quote and single-quote branches. Verified on mistune 3.2.0 (Apple M2, Python 3.14.3):\n- Reduces N=25 from 4.2 seconds to 0.000006 seconds (700,000x improvement)\n- Handles N=50 in 0.000008 seconds\n- Passes all existing functional tests (quoted titles, escaped quotes, escaped punctuation)",
"severity" : [ {
"type" : "CVSS_V4",
"score" : "CVSS:4.0/AV:N/AC:L/AT:N/PR:N/UI:N/VC:N/VI:N/VA:H/SC:N/SI:N/SA:N"
} ],
"affected" : [ {
"package" : {
"ecosystem" : "PyPI",
"name" : "mistune"
},
"ranges" : [ {
"type" : "ECOSYSTEM",
"events" : [ {
"introduced" : "3.0.0a1"
}, {
"fixed" : "3.2.1"
} ]
} ],
"database_specific" : {
"last_known_affected_version_range" : "<= 3.2.0"
}
} ],
"references" : [ {
"type" : "WEB",
"url" : "https://github.com/lepture/mistune/security/advisories/GHSA-8mp2-v27r-99xp"
}, {
"type" : "ADVISORY",
"url" : "https://nvd.nist.gov/vuln/detail/CVE-2026-33079"
}, {
"type" : "PACKAGE",
"url" : "https://github.com/lepture/mistune"
}, {
"type" : "WEB",
"url" : "https://github.com/lepture/mistune/blob/df23edd60b43b639d2e6760ef9dd3d618aa11c21/src/mistune/helpers.py#L20-L25"
} ],
"database_specific" : {
"cwe_ids" : [ "CWE-1333" ],
"severity" : "HIGH",
"github_reviewed" : true,
"github_reviewed_at" : "2026-05-06T16:52:43Z",
"nvd_published_at" : "2026-05-06T18:16:03Z"
}
}