{"id":"CVE-2026-59923","aliases":["DEBIAN-CVE-2026-59923","EUVD-2026-42331","GHSA-8c25-4j27-2rv3","PYSEC-2026-2211","SUSE-SU-2026:22655-1","UBUNTU-CVE-2026-59923","openSUSE-SU-2026:21339-1"],"status":"published","title":"Mistune: XSS via percent-encoded javascript URI bypass in safe_url()","description":"Mistune is a Python Markdown parser with renderers and plugins. Prior to 3.3.0, HTMLRenderer.safe_url() does not block percent-encoded javascript URIs, allowing attacker-supplied Markdown links or images to bypass URL protections and execute script in rendered HTML. This issue is fixed in version 3.3.0.","severity":{"version":"3.1","score":6.1,"vector":"CVSS:3.1/AV:N/AC:L/PR:N/UI:R/S:C/C:L/I:L/A:N","level":"medium","assessor":"cna","from":"cve"},"epss":{"day":"2026-11-11","score":0.00348,"percentile":0.28793,"model":"v2026.06.15"},"facts":{"in_kev":false,"known_exploited":false,"public_exploit":false,"fix_available":true},"cwes":["CWE-79"],"published":"2026-07-08T16:14:39Z","modified":"2026-10-28T02:30:54Z","fixes":[{"ecosystem":"PyPI","package":"mistune","fixed_in":["3.3.0"],"sources":["ghsa","osv"]}],"affected":[{"source":"ghsa","ecosystem":"PyPI","package":"mistune","ranges":[{"type":"ECOSYSTEM","events":[{"introduced":"0"},{"fixed":"3.3.0"}]}]},{"source":"osv","ecosystem":"Debian:12","package":"mistune","ranges":[{"type":"ECOSYSTEM","events":[{"introduced":"0"}]}],"versions":["2.0.4-1","2.0.4-2","3.0.2-1","3.0.2-2","3.1.3-1","3.1.4-1","3.3.4-1","3.4.0-1"]},{"source":"osv","ecosystem":"Debian:13","package":"mistune","ranges":[{"type":"ECOSYSTEM","events":[{"introduced":"0"}]}],"versions":["3.1.3-1","3.1.4-1","3.3.4-1","3.4.0-1"]},{"source":"osv","ecosystem":"Debian:14","package":"mistune","ranges":[{"type":"ECOSYSTEM","events":[{"introduced":"0"}]}],"versions":["3.1.3-1","3.1.4-1","3.3.4-1","3.4.0-1"]},{"source":"osv","ecosystem":"PyPI","package":"mistune","ranges":[{"type":"ECOSYSTEM","events":[{"introduced":"0"},{"fixed":"3.3.0"}]}],"versions":["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.0.0","2.0.0a1","2.0.0a2","2.0.0a3","2.0.0a4","2.0.0a5","2.0.0a6","2.0.0rc1","2.0.1","2.0.2","2.0.3","2.0.4","2.0.5","2.1.0","3.0.0","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.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"]},{"source":"osv","ecosystem":"PyPI","package":"mistune","ranges":[{"type":"ECOSYSTEM","events":[{"introduced":"0"},{"fixed":"3.3.0"}]}],"versions":["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.0.0","2.0.0a1","2.0.0a2","2.0.0a3","2.0.0a4","2.0.0a5","2.0.0a6","2.0.0rc1","2.0.1","2.0.2","2.0.3","2.0.4","2.0.5","2.1.0","3.0.0","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.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"]},{"source":"osv","ecosystem":"SUSE:Linux Enterprise Server 16.0","package":"python-mistune","ranges":[{"type":"ECOSYSTEM","events":[{"introduced":"0"},{"fixed":"3.1.3-160000.5.1"}]}],"bundled":10},{"source":"osv","ecosystem":"SUSE:Linux Enterprise Server for SAP applications 16.0","package":"python-mistune","ranges":[{"type":"ECOSYSTEM","events":[{"introduced":"0"},{"fixed":"3.1.3-160000.5.1"}]}],"bundled":10},{"source":"osv","ecosystem":"Ubuntu:16.04:LTS","package":"mistune","ranges":[{"type":"ECOSYSTEM","events":[{"introduced":"0"}]}],"versions":["0.6-2","0.7.1-1"]},{"source":"osv","ecosystem":"Ubuntu:18.04:LTS","package":"mistune","ranges":[{"type":"ECOSYSTEM","events":[{"introduced":"0"}]}],"versions":["0.7.4-1","0.8-1","0.8.1-1","0.8.3-2"]},{"source":"osv","ecosystem":"Ubuntu:20.04:LTS","package":"mistune","ranges":[{"type":"ECOSYSTEM","events":[{"introduced":"0"}]}],"versions":["0.8.4-1","0.8.4-2"]},{"source":"osv","ecosystem":"Ubuntu:22.04:LTS","package":"mistune","ranges":[{"type":"ECOSYSTEM","events":[{"introduced":"0"}]}],"versions":["0.8.4-4","0.8.4-5","2.0.0-1+really0.8.4-1"]},{"source":"osv","ecosystem":"Ubuntu:24.04:LTS","package":"mistune","ranges":[{"type":"ECOSYSTEM","events":[{"introduced":"0"}]}],"versions":["2.0.4-2","3.0.2-1"]},{"source":"osv","ecosystem":"Ubuntu:25.10","package":"mistune","ranges":[{"type":"ECOSYSTEM","events":[{"introduced":"0"}]}],"versions":["3.0.2-2","3.1.3-1"]},{"source":"osv","ecosystem":"Ubuntu:26.10","package":"mistune","ranges":[{"type":"ECOSYSTEM","events":[{"introduced":"0"}]}],"versions":["3.1.4-1"]},{"source":"osv","ecosystem":"Ubuntu:26.04:LTS","package":"mistune","ranges":[{"type":"ECOSYSTEM","events":[{"introduced":"0"}]}],"versions":["3.1.3-1","3.1.4-1"]},{"source":"osv","ecosystem":"openSUSE:Leap 16.0","package":"python-mistune","ranges":[{"type":"ECOSYSTEM","events":[{"introduced":"0"},{"fixed":"3.1.3-160000.5.1"}]}],"bundled":10}],"products":[{"vendor":"lepture","product":"mistune"},{"vendor":"mistune_project","product":"mistune"}],"references":[{"url":"https://github.com/lepture/mistune/security/advisories/GHSA-8c25-4j27-2rv3","tags":["x_refsource_CONFIRM","exploit","Exploit","Vendor Advisory","advisory","web","evidence","report"]},{"url":"https://github.com/lepture/mistune/commit/c7101fcbb6e8790e8e39157c5ca2238fc6dd6cbc","tags":["x_refsource_MISC","Patch","fix","web"]},{"url":"https://github.com/lepture/mistune/releases/tag/v3.3.0","tags":["x_refsource_MISC","Release Notes","web","advisory"]},{"url":"https://nvd.nist.gov/vuln/detail/CVE-2026-59923","tags":["advisory"]},{"url":"https://github.com/pypa/advisory-database/tree/main/vulns/mistune/PYSEC-2026-2211.yaml","tags":["web"]},{"url":"https://github.com/advisories/GHSA-8c25-4j27-2rv3"},{"url":"https://github.com/CVEProject/cvelistV5/tree/main/cves/2026/59xxx/CVE-2026-59923.json","tags":["advisory"]},{"url":"https://security-tracker.debian.org/tracker/CVE-2026-59923","tags":["advisory"]},{"url":"https://github.com/lepture/mistune","tags":["package"]},{"url":"https://www.suse.com/support/update/announcement/2026/suse-su-202622655-1/","tags":["advisory"]},{"url":"https://bugzilla.suse.com/1271082","tags":["report"]},{"url":"https://bugzilla.suse.com/1271117","tags":["report"]},{"url":"https://bugzilla.suse.com/1271119","tags":["report"]},{"url":"https://bugzilla.suse.com/1271121","tags":["report"]},{"url":"https://bugzilla.suse.com/1271125","tags":["report"]},{"url":"https://bugzilla.suse.com/1271127","tags":["report"]},{"url":"https://bugzilla.suse.com/1271128","tags":["report"]},{"url":"https://bugzilla.suse.com/1271131","tags":["report"]},{"url":"https://bugzilla.suse.com/1271132","tags":["report"]},{"url":"https://www.suse.com/security/cve/CVE-2026-44896","tags":["web"]},{"url":"https://www.suse.com/security/cve/CVE-2026-59922","tags":["web"]},{"url":"https://www.suse.com/security/cve/CVE-2026-59923","tags":["web"]},{"url":"https://www.suse.com/security/cve/CVE-2026-59924","tags":["web"]},{"url":"https://www.suse.com/security/cve/CVE-2026-59925","tags":["web"]},{"url":"https://www.suse.com/security/cve/CVE-2026-59926","tags":["web"]},{"url":"https://www.suse.com/security/cve/CVE-2026-59927","tags":["web"]},{"url":"https://www.suse.com/security/cve/CVE-2026-59928","tags":["web"]},{"url":"https://www.suse.com/security/cve/CVE-2026-59929","tags":["web"]},{"url":"https://www.suse.com/security/cve/CVE-2026-59930","tags":["web"]},{"url":"https://ubuntu.com/security/CVE-2026-59923","tags":["report"]},{"url":"https://www.cve.org/CVERecord?id=CVE-2026-59923","tags":["report"]},{"url":"","tags":["advisory"]}],"sources":{"cve":[{"id":"CVE-2026-59923","title":"Mistune: XSS via percent-encoded javascript URI bypass in safe_url()","description":"Mistune is a Python Markdown parser with renderers and plugins. Prior to 3.3.0, HTMLRenderer.safe_url() does not block percent-encoded javascript URIs, allowing attacker-supplied Markdown links or images to bypass URL protections and execute script in rendered HTML. This issue is fixed in version 3.3.0.","status":"published","published":"2026-07-08T16:14:39.266Z","modified":"2026-07-08T16:41:52.111Z","cvss":[{"version":"3.1","score":6.1,"vector":"CVSS:3.1/AV:N/AC:L/PR:N/UI:R/S:C/C:L/I:L/A:N","level":"medium","assessor":"cna"}],"cwes":["CWE-79"],"updated_at":"2026-11-02T14:19:58.560602Z"}],"euvd":[{"id":"EUVD-2026-42331","description":"Mistune is a Python Markdown parser with renderers and plugins. Prior to 3.3.0, HTMLRenderer.safe_url() does not block percent-encoded javascript URIs, allowing attacker-supplied Markdown links or images to bypass URL protections and execute script in rendered HTML. This issue is fixed in version 3.3.0.","status":"published","published":"2026-07-08T16:14:39Z","modified":"2026-07-08T16:41:52Z","cvss":[{"version":"3.1","score":6.1,"vector":"CVSS:3.1/AV:N/AC:L/PR:N/UI:R/S:C/C:L/I:L/A:N","level":"medium"}],"updated_at":"2026-11-02T18:20:10.578977Z"}],"ghsa":[{"id":"GHSA-8c25-4j27-2rv3","title":"Mistune: XSS via percent-encoded javascript URI bypass in safe_url()","description":"### Summary\nAn XSS vulnerability in Mistune allows bypassing of safe_url() protections via percent-encoded javascript URIs.\n\n\n### Details\nThe vulnerability exists in HTMLRenderer.safe_url() in Mistune.\n\nThe function is intended to block harmful URL schemes such as \"javascript:\" by checking the prefix of the provided URL:\n\n    _url = url.lower()\n    if _url.startswith(self.HARMFUL_PROTOCOLS):\n        return \"#harmful-link\"\n\nHowever, 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:\n\n    javascript%3Aalert(1)\n\nSince \"%3A\" is not decoded to \":\", the check does not detect the \"javascript:\" scheme.\n\nWhen rendered in a browser, the URL is decoded, resulting in execution of arbitrary JavaScript upon user interaction.\n\nThis effectively bypasses Mistune's built-in safe_url() protection mechanism.\n\n\n\n### PoC\n1. Install vulnerable version:\n\n    pip install mistune==3.2.0\n\n2. Run the following code:\n\n    import mistune\n\n    markdown = mistune.create_markdown()\n    html = markdown(\"[j](javascript%3Aalert(1))\")\n\n    print(html)\n\n3. Output:\n\n    \u003cp\u003e\u003ca href=\"javascript%3Aalert(1)\"\u003ej\u003c/a\u003e\u003c/p\u003e\n\n4. Open the rendered HTML in a browser and click the link.\n\n5. The browser decodes \"%3A\" into \":\" and executes:\n\n    javascript:alert(1)\n\n\n### Impact\nThis is a cross-site scripting (XSS) vulnerability.\n\nAn attacker can craft a malicious Markdown link that executes JavaScript in the victim's browser when clicked.\n\nImpact includes:\n- Session hijacking (e.g., cookie theft)\n- Execution of arbitrary JavaScript in the victim's context\n- Potential account takeover depending on the application\n\nThis affects any application that renders user-controlled Markdown using Mistune without additional URL sanitization.","status":"published","published":"2026-07-20T21:32:49Z","modified":"2026-07-20T21:32:52Z","cvss":[{"version":"3.1","score":6.1,"vector":"CVSS:3.1/AV:N/AC:L/PR:N/UI:R/S:C/C:L/I:L/A:N","level":"medium"}],"cwes":["CWE-79"],"updated_at":"2026-11-02T14:40:48.410776Z"}],"nvd":[{"id":"CVE-2026-59923","description":"Mistune is a Python Markdown parser with renderers and plugins. Prior to 3.3.0, HTMLRenderer.safe_url() does not block percent-encoded javascript URIs, allowing attacker-supplied Markdown links or images to bypass URL protections and execute script in rendered HTML. This issue is fixed in version 3.3.0.","status":"published","published":"2026-07-08T17:17:27.91Z","modified":"2026-10-25T17:10:00.197Z","cvss":[{"version":"3.1","score":6.1,"vector":"CVSS:3.1/AV:N/AC:L/PR:N/UI:R/S:C/C:L/I:L/A:N","level":"medium","assessor":"secondary"}],"cwes":["CWE-79"],"updated_at":"2026-11-02T14:12:28.040501Z"}],"osv":[{"id":"CVE-2026-59923","title":"Mistune: XSS via percent-encoded javascript URI bypass in safe_url()","description":"Mistune is a Python Markdown parser with renderers and plugins. Prior to 3.3.0, HTMLRenderer.safe_url() does not block percent-encoded javascript URIs, allowing attacker-supplied Markdown links or images to bypass URL protections and execute script in rendered HTML. This issue is fixed in version 3.3.0.","status":"published","published":"2026-07-08T16:14:39.266Z","modified":"2026-10-28T02:30:54.789864845Z","cvss":[{"version":"3.1","score":6.1,"vector":"CVSS:3.1/AV:N/AC:L/PR:N/UI:R/S:C/C:L/I:L/A:N","level":"medium"}],"cwes":["CWE-79"],"updated_at":"2026-11-02T15:45:12.496548Z"},{"id":"DEBIAN-CVE-2026-59923","description":"Mistune is a Python Markdown parser with renderers and plugins. Prior to 3.3.0, HTMLRenderer.safe_url() does not block percent-encoded javascript URIs, allowing attacker-supplied Markdown links or images to bypass URL protections and execute script in rendered HTML. This issue is fixed in version 3.3.0.","status":"published","published":"2026-07-08T17:17:27.91Z","modified":"2026-10-26T12:02:35.883601699Z","cvss":[{"version":"3.1","score":6.1,"vector":"CVSS:3.1/AV:N/AC:L/PR:N/UI:R/S:C/C:L/I:L/A:N","level":"medium"}],"updated_at":"2026-11-02T15:45:57.932517Z"},{"id":"GHSA-8c25-4j27-2rv3","title":"Mistune: XSS via percent-encoded javascript URI bypass in safe_url()","description":"### Summary\nAn XSS vulnerability in Mistune allows bypassing of safe_url() protections via percent-encoded javascript URIs.\n\n\n### Details\nThe vulnerability exists in HTMLRenderer.safe_url() in Mistune.\n\nThe function is intended to block harmful URL schemes such as \"javascript:\" by checking the prefix of the provided URL:\n\n    _url = url.lower()\n    if _url.startswith(self.HARMFUL_PROTOCOLS):\n        return \"#harmful-link\"\n\nHowever, 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:\n\n    javascript%3Aalert(1)\n\nSince \"%3A\" is not decoded to \":\", the check does not detect the \"javascript:\" scheme.\n\nWhen rendered in a browser, the URL is decoded, resulting in execution of arbitrary JavaScript upon user interaction.\n\nThis effectively bypasses Mistune's built-in safe_url() protection mechanism.\n\n\n\n### PoC\n1. Install vulnerable version:\n\n    pip install mistune==3.2.0\n\n2. Run the following code:\n\n    import mistune\n\n    markdown = mistune.create_markdown()\n    html = markdown(\"[j](javascript%3Aalert(1))\")\n\n    print(html)\n\n3. Output:\n\n    \u003cp\u003e\u003ca href=\"javascript%3Aalert(1)\"\u003ej\u003c/a\u003e\u003c/p\u003e\n\n4. Open the rendered HTML in a browser and click the link.\n\n5. The browser decodes \"%3A\" into \":\" and executes:\n\n    javascript:alert(1)\n\n\n### Impact\nThis is a cross-site scripting (XSS) vulnerability.\n\nAn attacker can craft a malicious Markdown link that executes JavaScript in the victim's browser when clicked.\n\nImpact includes:\n- Session hijacking (e.g., cookie theft)\n- Execution of arbitrary JavaScript in the victim's context\n- Potential account takeover depending on the application\n\nThis affects any application that renders user-controlled Markdown using Mistune without additional URL sanitization.","status":"published","published":"2026-07-20T21:32:49Z","modified":"2026-07-20T21:46:43.351006286Z","cvss":[{"version":"3.1","score":6.1,"vector":"CVSS:3.1/AV:N/AC:L/PR:N/UI:R/S:C/C:L/I:L/A:N","level":"medium"}],"cwes":["CWE-79"],"updated_at":"2026-11-02T15:46:42.077781Z"},{"id":"PYSEC-2026-2211","description":"Mistune is a Python Markdown parser with renderers and plugins. Prior to 3.3.0, HTMLRenderer.safe_url() does not block percent-encoded javascript URIs, allowing attacker-supplied Markdown links or images to bypass URL protections and execute script in rendered HTML. This issue is fixed in version 3.3.0.","status":"published","published":"2026-07-08T17:17:27.91Z","modified":"2026-07-13T07:15:29.095933312Z","cvss":[{"version":"3.1","score":6.1,"vector":"CVSS:3.1/AV:N/AC:L/PR:N/UI:R/S:C/C:L/I:L/A:N","level":"medium"}],"updated_at":"2026-11-02T15:52:55.537808Z"},{"id":"UBUNTU-CVE-2026-59923","description":"Mistune is a Python Markdown parser with renderers and plugins. Prior to 3.3.0, HTMLRenderer.safe_url() does not block percent-encoded javascript URIs, allowing attacker-supplied Markdown links or images to bypass URL protections and execute script in rendered HTML. This issue is fixed in version 3.3.0.","status":"published","published":"2026-07-08T17:17:00Z","modified":"2026-10-17T12:57:17.739945738Z","cvss":[{"version":"3.1","score":6.1,"vector":"CVSS:3.1/AV:N/AC:L/PR:N/UI:R/S:C/C:L/I:L/A:N","level":"medium"}],"updated_at":"2026-11-02T16:56:41.911783Z"},{"id":"openSUSE-SU-2026:21339-1","title":"Security update for python-mistune","description":"This update for python-mistune fixes the following issues\n\n- CVE-2026-59922: quadratic-time parsing on long runs of some markers in `formatting.py` can lead to DoS (bsc#1271117).\n- CVE-2026-59923: `HTMLRenderer.safe_url()` does not block percent-encoded javascript URIs and allows for XSS\n  (bsc#1271119).\n- CVE-2026-59924: improper processing of user-supplied include paths in `Include.parse()` can lead to path traversal\n  and arbitrary file reads (bsc#1271121).\n- CVE-2026-59925: quadratic-time parsing on long runs of some emphasis pairs in `inline_parser` can lead to DoS\n  (bsc#1271125).\n- CVE-2026-59926: improper escaping in `render_admonition()` can lead to atribute injection and XSS (bsc#1271127).\n- CVE-2026-59927: uncontrolled recursion when processing two markdown files that include each other can lead to a DoS\n   (bsc#1271128).\n- CVE-2026-59928: quadratic-time parsing on long lists of repeated reference-link definitions in `block_parser` can\n  lead to DoS (bsc#1271131).\n- CVE-2026-59929: HARMFUL_PROTOCOLS list misses legacy and chained schemes and allow arbitrary script execution in\n  user agents (bsc#1271132).\n- CVE-2026-59930: the `toc` plugin and `TableOfContents` directive generate heading IDs with predictable values and\n  allow for collisions with attacker-controlled `id=\"toc_N\"` content (bsc#1271082).\n","status":"published","published":"2026-07-14T10:41:18Z","modified":"2026-07-15T10:00:11.548963212Z","updated_at":"2026-11-02T16:58:41.885092Z"},{"id":"SUSE-SU-2026:22655-1","title":"Security update for python-mistune","description":"This update for python-mistune fixes the following issues\n\n- CVE-2026-59922: quadratic-time parsing on long runs of some markers in `formatting.py` can lead to DoS (bsc#1271117).\n- CVE-2026-59923: `HTMLRenderer.safe_url()` does not block percent-encoded javascript URIs and allows for XSS\n  (bsc#1271119).\n- CVE-2026-59924: improper processing of user-supplied include paths in `Include.parse()` can lead to path traversal\n  and arbitrary file reads (bsc#1271121).\n- CVE-2026-59925: quadratic-time parsing on long runs of some emphasis pairs in `inline_parser` can lead to DoS\n  (bsc#1271125).\n- CVE-2026-59926: improper escaping in `render_admonition()` can lead to atribute injection and XSS (bsc#1271127).\n- CVE-2026-59927: uncontrolled recursion when processing two markdown files that include each other can lead to a DoS\n   (bsc#1271128).\n- CVE-2026-59928: quadratic-time parsing on long lists of repeated reference-link definitions in `block_parser` can\n  lead to DoS (bsc#1271131).\n- CVE-2026-59929: HARMFUL_PROTOCOLS list misses legacy and chained schemes and allow arbitrary script execution in\n  user agents (bsc#1271132).\n- CVE-2026-59930: the `toc` plugin and `TableOfContents` directive generate heading IDs with predictable values and\n  allow for collisions with attacker-controlled `id=\"toc_N\"` content (bsc#1271082).\n","status":"published","published":"2026-07-14T10:37:38Z","modified":"2026-07-17T18:24:05.645518218Z","updated_at":"2026-11-02T15:54:03.080707Z"}]}}
