GHSA-8c25-4j27-2rv3

Mistune: XSS via percent-encoded javascript URI bypass in safe_url()

At a glance

Published
Updated
CVE
CVE-2026-59923
Aliases
PYSEC-2026-2211
CVSS_V3
CVSS:3.1/AV:N/AC:L/PR:N/UI:R/S:C/C:L/I:L/A:N

Description

### Summary An XSS vulnerability in Mistune allows bypassing of safe_url() protections via percent-encoded javascript URIs. ### Details 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. ### PoC 1. Install vulnerable version: pip install mistune==3.2.0 2. Run the following code: import mistune markdown = mistune.create_markdown() html = markdown("[j](javascript%3Aalert(1))") print(html) 3. Output: <p><a href="javascript%3Aalert(1)">j</a></p> 4. Open the rendered HTML in a browser and click the link. 5. The browser decodes "%3A" into ":" and executes: javascript:alert(1) ### Impact 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: - Session hijacking (e.g., cookie theft) - Execution of arbitrary JavaScript in the victim's context - Potential account takeover depending on the application This affects any application that renders user-controlled Markdown using Mistune without additional URL sanitization.

Affected packages

PackageVersions
PyPI · mistuneintroduced 0, fixed 3.3.0

References

Sources

SourceLicence
OSV.devCC-BY 4.0 — GitHub Advisory Database