| Package | Affected versions | Patched versions |
|---|---|---|
| mistune | < 3.3.0 | 3.3.0 |
| mistune | < 3.3.0 | 3.3.0 |
An XSS vulnerability in Mistune allows bypassing of safe_url() protections via percent-encoded javascript URIs.
The vulnerability exists in HTMLRenderer.safe_url() in Mistune.
The function is intended to block harmful URL schemes such as "javascript:" by checking the prefix of the provided URL:
_url = url.lower()
if _url.startswith(self.HARMFUL_PROTOCOLS):
return "#harmful-link"
However, 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:
javascript%3Aalert(1)
Since "%3A" is not decoded to ":", the check does not detect the "javascript:" scheme.
When rendered in a browser, the URL is decoded, resulting in execution of arbitrary JavaScript upon user interaction.
This effectively bypasses Mistune's built-in safe_url() protection mechanism.
Install vulnerable version:
pip install mistune==3.2.0
Run the following code:
import mistune
markdown = mistune.create_markdown() html = markdown("j")
print(html)
Output:
<p><a href="javascript%3Aalert(1)">j</a></p>Open the rendered HTML in a browser and click the link.
The browser decodes "%3A" into ":" and executes:
javascript:alert(1)
This is a cross-site scripting (XSS) vulnerability.
An attacker can craft a malicious Markdown link that executes JavaScript in the victim's browser when clicked.
Impact includes:
This affects any application that renders user-controlled Markdown using Mistune without additional URL sanitization.
Running one of these products? Scan your site to see whether it exposes a vulnerable version.
Scan my site free