🛡️ CVE-2026-59929 — mistune

🟡 CVSS 6.1 — Medium ⚠️ Exploit Public CWE-184 OSV
6.1
CVSS Score
0 Low4 Medium7 High9 Critical10

Description

Mistune renderers/html.safe_url: HARMFUL_PROTOCOLS list misses legacy and chained schemes that historically chain to javascript: execution

Summary

Type: URL-scheme allowlist gap. The safe_url filter only blocks the four schemes javascript:, vbscript:, file:, data:. Several other schemes are accepted into rendered <a href="..."> and <img src="..."> tags despite being known XSS vectors in legacy or chain-handling browsers. The same gap applies to direct links, reference links, and autolinks.

File: src/mistune/renderers/html.py, line 11-23 (HARMFUL_PROTOCOLS list).

Root cause: the HARMFUL_PROTOCOLS tuple is a hardcoded, opt-out denylist of four entries. Browsers historically supported (and some still partially support) several other schemes that either execute JavaScript directly (livescript:, mocha:) or wrap a javascript: payload (feed:javascript:, view-source:javascript:, jar:javascript:, ms-its:javascript:, mk:@MSITStore:javascript:). On user-agents that still recognise these schemes (older Firefox builds for feed:/jar:, all Internet Explorer / Edge Legacy for ms-its:/mk:/res:, niche chrome-style browsers, browser extensions that register custom protocol handlers), clicking a link rendered by mistune executes attacker-controlled JavaScript in the page's origin.

Affected Code

File: src/mistune/renderers/html.py, lines 10-62.

```python

class HTMLRenderer(BaseRenderer):

HARMFUL_PROTOCOLS: ClassVar[Tuple[str, ...]] = (

"javascript:",

"vbscript:",

"file:",

"data:",

) # <-- BUG: incomplete denylist

GOOD_DATA_PROTOCOLS: ClassVar[Tuple[str, ...]] = (

"data:image/gif;",

"data:image/png;",

"data:image/jpeg;",

"data:image/webp;",

)

def safe_url(self, url: str) -> str:

if self._allow_harmful_protocols is True:

return escape_text(url)

_url = url.lower()

if self._allow_harmful_protocols and _url.startswith(tuple(self._allow_harmful_protocols)):

return escape_text(url)

if _url.startswith(self.HARMFUL_PROTOCOLS) and not _url.startswith(self.GOOD_DATA_PROTOCOLS):

return "#harmful-link"

return escape_text(url) # <-- BUG: any scheme not in HARMFUL_PROTOCOLS passes through

```

Why it's wrong: an opt-out denylist for URL schemes is the wrong shape. The set of schemes a user-agent might honour is unbounded (registered handlers, browser extensions, OS-level protocol registrations, custom intent handlers on Android, etc.), but the set of schemes a markdown renderer needs to allow is small (http://, https://, mailto:, optionally tel:, ftp:, fragment-only #anchor, and a few image-only data: types). Switching to an opt-in allowlist with a safe_extra_protocols knob for callers who need others would close every variant of this bug class permanently. The current code accepts every chained-scheme XSS vector for as long as the project remembers to keep the denylist current.

Exploit Chain

1. Application accepts attacker-supplied markdown and renders it with mistune. The default escape=True prevents raw HTML, but link href/image src filtering is the only XSS defense for [click](...) and ![alt](...) syntax.

2. Attacker writes [click here](feed:javascript:alert(document.cookie)). mistune's safe_url checks feed:javascript:alert(document.cookie) against HARMFUL_PROTOCOLS = ('javascript:', 'vbscript:', 'file:', 'data:') — none match. The href is escape_text'd (HTML-entity escape) and emitted as <a href="feed:javascript:alert(document.cookie)">click here</a>.

3. Victim using a Firefox build that still has the feed handler registered (extension, configuration, or LTS that retained the feed reader past the 64.0 removal — including some forks and ESR builds) clicks the link. Firefox's feed handler invokes the inner URL, which is javascript:alert(...). JS executes in the page's origin. Victim's session cookie is exfiltrated.

4. Same pattern for livescript:alert(1) (Netscape Communicator era, still recognised by some niche browsers / browser-emulator tools), view-source:javascript:alert(1) (Firefox, see CVE-2009-1938), jar:javascript:alert(1) (older Firefox), ms-its:javascript: (IE/Edge Legacy), res:javascript: (IE), mk:@MSITStore:javascript: (IE CHM viewer). Each user-agent that recognises one of these is exploitable; the user-agent population that recognises at least one is not negligible (corporate environments still running Edge Legacy compatibility mode, locked-down kiosk browsers, Android WebView in apps that register custom intent handlers, Linux distros with old Firefox ESR plus the feed: extension, etc.).

The same primitive applies to image src (![](feed:javascript:...) rendered as <img src="feed:...">) — though most browsers don't fetch javascript: from img src, the

How this vulnerability can be exploited

This issue can be reached over the network, attack complexity is low, an attacker needs no privileges on the target. A user must be tricked into taking some action. The scope is changed, meaning a successful attack can affect components beyond the vulnerable one. Rated impact: confidentiality low, integrity low, availability none.

Affected software

CVE-2026-59929 is recorded against 1 package.

  • mistune (fixed in 3.3.0)

Timeline and source

Published on 20 July 2026. A public exploit is known to exist, which raises the urgency of patching considerably. A vendor advisory or fix has been published. Record sourced from OSV.

References

github.com (Web)
nvd.nist.gov (Advisory)
github.com (Web)
github.com (Package)
github.com (Web)
github.com (Web)

Details

Severity MEDIUM
CVSS Score 6.1
CVSS Vector CVSS:3.1/AV:N/AC:L/PR:N/UI:R/S:C/C:L/I:L/A:N
CWE CWE-184
Public Exploit ⚠️ Yes
Source OSV
Published 2026-07-20
Updated 2026-08-12
Modified 2026-07-20

Affected Packages

Software From version Fixed in
mistune 3.3.0

Similar Threats

Exploit Protection

Are you running mistune?

CVE-2026-59929 carries CVSS 6.1 Medium rating and a public exploit already exists. BotEraser checks your installation against this and other known CVE records, and blocks IPs associated with exploit activity.

Check My Site For CVE-2026-59929 →

No credit card required  ·  Results in minutes

ⓘ Data Notice: The information presented above has been compiled from publicly available internet sources. Boteraser aggregates this data solely for informational purposes and does not independently classify, evaluate, or endorse any findings about the vulnerabilities listed. The accuracy and completeness of this information is the sole responsibility of the original publishers. Boteraser and its operators accept no liability for any decisions made based on this data.