GHSA-8c25-4j27-2rv3

Suggest an improvement
Source
https://github.com/advisories/GHSA-8c25-4j27-2rv3
Import Source
https://github.com/github/advisory-database/blob/main/advisories/github-reviewed/2026/07/GHSA-8c25-4j27-2rv3/GHSA-8c25-4j27-2rv3.json
JSON Data
https://api.test.osv.dev/v1/vulns/GHSA-8c25-4j27-2rv3
Aliases
Published
2026-07-20T21:32:49Z
Modified
2026-07-20T21:46:40Z
Severity
  • 6.1 (Medium) CVSS_V3 - CVSS:3.1/AV:N/AC:L/PR:N/UI:R/S:C/C:L/I:L/A:N CVSS Calculator
Summary
Mistune: XSS via percent-encoded javascript URI bypass in safe_url()
Details

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")

    print(html)

  3. Output:

    j

  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.

Database specific
{
    "cwe_ids":  [
        "CWE-79"
    ],
    "github_reviewed":  true,
    "github_reviewed_at":  "2026-07-20T21:32:49Z",
    "nvd_published_at":  "2026-07-08T17:17:27Z",
    "severity":  "MODERATE"
}
References

Affected packages

PyPI / mistune

Package

Affected ranges

Type
ECOSYSTEM
Events
Introduced
0 Unknown introduced version / All previous versions are affected
Fixed
3.3.0

Affected versions

0.*
0.1.0
0.2.0
0.3.0
0.3.1
0.4
0.4.1
0.5
0.5.1
0.6
0.7
0.7.1
0.7.2
0.7.3
0.7.4
0.8
0.8.1
0.8.2
0.8.3
0.8.4
2.*
2.0.0a1
2.0.0a2
2.0.0a3
2.0.0a4
2.0.0a5
2.0.0a6
2.0.0rc1
2.0.0
2.0.1
2.0.2
2.0.3
2.0.4
2.0.5
2.1.0
3.*
3.0.0a1
3.0.0a2
3.0.0a3
3.0.0rc1
3.0.0rc2
3.0.0rc3
3.0.0rc4
3.0.0rc5
3.0.0
3.0.1
3.0.2
3.1.0
3.1.1
3.1.2
3.1.3
3.1.4
3.2.0
3.2.1

Database specific

source
"https://github.com/github/advisory-database/blob/main/advisories/github-reviewed/2026/07/GHSA-8c25-4j27-2rv3/GHSA-8c25-4j27-2rv3.json"