CVE-2026-59929 Overview
CVE-2026-59929 affects Mistune, a Python Markdown parser with pluggable renderers. The safe_url filter in src/mistune/renderers/html.py blocks only javascript:, vbscript:, file:, and data: URI schemes. Legacy and chained schemes such as feed:, view-source:, jar:, livescript:, mocha:, ms-its:, mk:, and res: pass through the filter unchanged. Attackers can embed these schemes in Markdown links or image sources rendered into href and src attributes. In affected user agents, this behavior leads to cross-site scripting (XSS) [CWE-79]. The maintainers fixed the issue in Mistune 3.3.0.
Critical Impact
Attacker-controlled Markdown can execute script in browsers that honor legacy or chained URI schemes, enabling stored or reflected XSS in applications that render untrusted Markdown with Mistune versions prior to 3.3.0.
Affected Products
- Mistune Python Markdown parser prior to version 3.3.0
- Applications embedding Mistune to render untrusted Markdown to HTML
- Downstream Python projects and documentation pipelines depending on vulnerable Mistune releases
Discovery Timeline
- 2026-07-08 - CVE-2026-59929 published to NVD
- 2026-07-08 - Last updated in NVD database
Technical Details for CVE-2026-59929
Vulnerability Analysis
Mistune converts Markdown link and image tokens into HTML href and src attributes. The safe_url filter in src/mistune/renderers/html.py enforces scheme safety through an allowlist-style rejection of dangerous prefixes. The filter, however, only rejects javascript:, vbscript:, file:, and data:. Any other scheme reaches the rendered attribute unmodified. Several legacy or chained schemes retain script execution semantics in specific browsers or Markdown viewers. Examples include feed:javascript:..., view-source:javascript:..., jar:, livescript:, mocha:, ms-its:, mk:, and res:. When a user clicks a rendered link or a browser processes the attribute, the underlying handler can execute attacker-supplied script in the origin of the hosting page.
Root Cause
The root cause is an incomplete denylist of unsafe URI schemes combined with missing normalization of percent-encoded input. Because the filter did not call urllib.parse.unquote before comparison, encoded variants also evaded detection. The corrective commit adds from urllib.parse import unquote and decodes candidate URLs before scheme evaluation, tightening the check against both new schemes and encoded bypasses.
Attack Vector
Exploitation requires an application to render attacker-supplied Markdown with a vulnerable Mistune version and a victim to interact with the resulting page. The attacker crafts a Markdown link such as [click](feed:javascript:alert(1)) or an image with a comparable scheme. Rendering produces an href or src value that the browser resolves through a legacy handler, executing script in the application origin. User interaction is required, matching the CVSS UI:R component.
from typing import Any, ClassVar, Dict, Optional, Tuple, Literal
+from urllib.parse import unquote
from ..core import BaseRenderer, BlockState
from ..util import escape as escape_text
from ..util import safe_entity, striptags
Source: GitHub Commit c7101fc. The patch introduces unquote so the renderer normalizes percent-encoded schemes before applying the safety check.
Detection Methods for CVE-2026-59929
Indicators of Compromise
- Rendered HTML containing href or src values starting with feed:, view-source:, jar:, livescript:, mocha:, ms-its:, mk:, or res:.
- Markdown submissions containing chained scheme prefixes such as feed:javascript: or view-source:javascript:.
- Web server logs showing outbound clicks or referrers with legacy schemes originating from Markdown-rendered pages.
Detection Strategies
- Inspect stored user content for Markdown links and images whose URLs match the vulnerable scheme list before rendering.
- Add server-side or WAF rules that block requests containing Markdown payloads with feed:, jar:, or view-source: prefixes when Markdown input fields are involved.
- Use dependency scanners such as pip-audit or safety to flag Mistune installations below 3.3.0 across build and runtime environments.
Monitoring Recommendations
- Alert on browser console errors or Content Security Policy (CSP) violations referencing unusual URI handlers on pages that render user Markdown.
- Monitor package inventories for the pinned Mistune version and generate a finding when it resolves to a release earlier than 3.3.0.
- Track outbound navigation events from Markdown-rendered surfaces to identify attempts to invoke legacy protocol handlers.
How to Mitigate CVE-2026-59929
Immediate Actions Required
- Upgrade Mistune to version 3.3.0 or later in all Python environments that render untrusted Markdown.
- Rebuild and redeploy container images, serverless functions, and documentation pipelines that pin an older Mistune release.
- Re-scan stored user-generated Markdown for the affected scheme list and neutralize matching links before rerendering.
Patch Information
The fix is included in Mistune 3.3.0. Technical details are documented in GHSA-qfrw-5rxm-mhh2, and the code change is available in commit c7101fc. The commit imports urllib.parse.unquote and extends the safe_url filter to reject encoded and additional unsafe schemes.
Workarounds
- Wrap safe_url or the HTML renderer with an application-level allowlist that only permits http:, https:, and mailto: schemes.
- Apply a strict Content Security Policy (CSP) that disables inline script and restricts navigation to trusted schemes on pages rendering Markdown.
- Sanitize the rendered HTML with a downstream library such as bleach configured to strip disallowed URI schemes from href and src attributes.
# Upgrade Mistune across Python environments
pip install --upgrade "mistune>=3.3.0"
# Verify the installed version
python -c "import mistune; print(mistune.__version__)"
# Audit dependencies for vulnerable versions
pip-audit --strict
Disclaimer: This content was generated using AI. While we strive for accuracy, please verify critical information with official sources.

