From c50bbb6d9271f626db85207bf5e049935f46aa9c Mon Sep 17 00:00:00 2001 From: Abhijith A Date: Sun, 18 Oct 2026 22:41:02 +0530 Subject: [PATCH] Fix XSS in safe_mode via image tags missing _safe_href check Image tags (![](url)) in safe_mode do not validate the URL against _safe_href, unlike anchor tags which do. This allows javascript:, vbscript:, and other dangerous URL schemes through in attributes when safe_mode is enabled. Apply the same _safe_href check used for anchors to image src URLs, replacing the URL with an empty string when it fails validation. Co-Authored-By: Claude Opus 4.6 --- lib/markdown2.py | 2 ++ test/tm-cases/img_safe_mode_xss.html | 9 +++++++++ test/tm-cases/img_safe_mode_xss.opts | 1 + test/tm-cases/img_safe_mode_xss.text | 9 +++++++++ 4 files changed, 21 insertions(+) create mode 100644 test/tm-cases/img_safe_mode_xss.html create mode 100644 test/tm-cases/img_safe_mode_xss.opts create mode 100644 test/tm-cases/img_safe_mode_xss.text diff --git a/lib/markdown2.py b/lib/markdown2.py index 66d49a69..6c18f3bb 100755 --- a/lib/markdown2.py +++ b/lib/markdown2.py @@ -3229,6 +3229,8 @@ def process_image(self, url: str, title_attr: str, link_text: str) -> Tuple[str, This section will be skipped by the link processor ''' img_class_str = self.md._html_class_str_from_tag("img") + if self.md.safe_mode and not self.md._safe_href.match(url): + url = '' result = ( f'{self.md._hash_span(_xml_escape_attr(link_text))}xss

+ +

xss

+ +

xss

+ +

safe

+ +

safe

diff --git a/test/tm-cases/img_safe_mode_xss.opts b/test/tm-cases/img_safe_mode_xss.opts new file mode 100644 index 00000000..ad487c04 --- /dev/null +++ b/test/tm-cases/img_safe_mode_xss.opts @@ -0,0 +1 @@ +{"safe_mode": "escape"} diff --git a/test/tm-cases/img_safe_mode_xss.text b/test/tm-cases/img_safe_mode_xss.text new file mode 100644 index 00000000..a13a1fa7 --- /dev/null +++ b/test/tm-cases/img_safe_mode_xss.text @@ -0,0 +1,9 @@ +![xss](javascript:alert(1)) + +![xss](JavaScript:alert(document.domain)) + +![xss](vbscript:MsgBox(1)) + +![safe](https://example.com/pic.png) + +![safe](./images/pic.png)