From 29b8523f670b64f06e757a8438f437b0e439e4f2 Mon Sep 17 00:00:00 2001 From: martgil <46025304+martgil@users.noreply.github.com> Date: Mon, 10 Aug 2026 13:25:18 +0800 Subject: [PATCH 1/3] feat: add srcset to forbidden HTML attribute --- extension/js/common/platform/xss.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/extension/js/common/platform/xss.ts b/extension/js/common/platform/xss.ts index 20cc682b07d..58d3cd3981d 100644 --- a/extension/js/common/platform/xss.ts +++ b/extension/js/common/platform/xss.ts @@ -47,7 +47,7 @@ export class Xss { 'col', ]; private static ADD_ATTR = ['email', 'page', 'addurltext', 'longid', 'index', 'target', 'fingerprint', 'cryptup-data']; - private static FORBID_ATTR = ['background']; + private static FORBID_ATTR = ['background', 'srcset']; private static HREF_REGEX_CACHE: RegExp | undefined; private static EMOJI_REGEX = /(?![*#0-9]+)[\p{Emoji}\p{Emoji_Modifier}\p{Emoji_Component}\p{Emoji_Modifier_Base}\p{Emoji_Presentation}]/gu; /* eslint-disable @typescript-eslint/naming-convention */ From f0f573833cecb3399bfeac45a826e9b1da0965b5 Mon Sep 17 00:00:00 2001 From: martgil <46025304+martgil@users.noreply.github.com> Date: Mon, 10 Aug 2026 13:27:27 +0800 Subject: [PATCH 2/3] test: add test for #6269 case --- .../tests/browser-unit-tests/unit-Xss.js | 39 +++++++++++++++++++ 1 file changed, 39 insertions(+) diff --git a/test/source/tests/browser-unit-tests/unit-Xss.js b/test/source/tests/browser-unit-tests/unit-Xss.js index 8b95ac0bf8c..c4ef7f46498 100644 --- a/test/source/tests/browser-unit-tests/unit-Xss.js +++ b/test/source/tests/browser-unit-tests/unit-Xss.js @@ -79,3 +79,42 @@ BROWSER_UNIT_TEST_NAME(`Xss.htmlSanitizeKeepBasicTags strips url() in CSS`); } return 'pass'; })(); + +BROWSER_UNIT_TEST_NAME(`Xss.htmlSanitizeKeepBasicTags strips srcset attribute from img`); +(async () => { + const dirty = ``; + const clean = Xss.htmlSanitizeKeepBasicTags(dirty, 'IMG-KEEP'); + if (/srcset/i.test(clean)) { + throw Error(`srcset was not stripped from sanitized HTML: ${clean}`); + } + if (!/src="cid:test-image"/.test(clean)) { + throw Error(`expected cid src to be preserved, got: ${clean}`); + } + return 'pass'; +})(); + +BROWSER_UNIT_TEST_NAME(`Xss.htmlSanitize (used for CID replacement) strips srcset attribute from img`); +(async () => { + const dirty = `inline`; + const clean = Xss.htmlSanitize(dirty); + if (/srcset/i.test(clean)) { + throw Error(`srcset was not stripped from sanitized HTML: ${clean}`); + } + if (!/src="cid:test-image"/.test(clean)) { + throw Error(`expected cid src to be preserved, got: ${clean}`); + } + return 'pass'; +})(); + +BROWSER_UNIT_TEST_NAME(`Xss.htmlSanitizeKeepBasicTags keeps srcset-less inline images and gates remote src`); +(async () => { + const dirty = ``; + const clean = Xss.htmlSanitizeKeepBasicTags(dirty, 'IMG-KEEP'); + if (/srcset/i.test(clean)) { + throw Error(`srcset was not stripped from sanitized HTML: ${clean}`); + } + if (!/remote_image_container/.test(clean)) { + throw Error(`expected remote src to be replaced with remote_image_container, got: ${clean}`); + } + return 'pass'; +})(); From f2cb067f115054701b461d03a60e7c5f6372f528 Mon Sep 17 00:00:00 2001 From: martgil <46025304+martgil@users.noreply.github.com> Date: Tue, 11 Aug 2026 18:49:09 +0800 Subject: [PATCH 3/3] feat: additional sanitation checks for image src attribute --- extension/js/common/platform/xss.ts | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/extension/js/common/platform/xss.ts b/extension/js/common/platform/xss.ts index 58d3cd3981d..ecda2a5e2ec 100644 --- a/extension/js/common/platform/xss.ts +++ b/extension/js/common/platform/xss.ts @@ -201,6 +201,11 @@ export class Xss { } else if (!src) { img.remove(); // src that exists but is null is suspicious } else if (imgHandling === 'IMG-KEEP' && checkValidURL(src)) { + const pathname = new URL(src).pathname.toLowerCase(); + if (pathname.includes('/logout') || pathname.includes('/signout')) { + img.remove(); + return; + } // replace remote image with remote_image_container const remoteImgEl = `