From 5ab76dc11d106d570c274cc8ae5ff92254966523 Mon Sep 17 00:00:00 2001 From: Joshua Provoste <8358462+JoshuaProvoste@users.noreply.github.com> Date: Thu, 2 Apr 2026 17:34:57 -0300 Subject: [PATCH] Security: Mitigate DOM-based XSS in resolveUrl and inner-h-t-m-l bindings --- lib/mixins/property-effects.js | 3 + lib/utils/resolve-url.js | 5 ++ test/unit/security.html | 103 +++++++++++++++++++++++++++++++++ 3 files changed, 111 insertions(+) create mode 100644 test/unit/security.html diff --git a/lib/mixins/property-effects.js b/lib/mixins/property-effects.js index 077c0064e6..3277be72a7 100644 --- a/lib/mixins/property-effects.js +++ b/lib/mixins/property-effects.js @@ -807,6 +807,9 @@ function applyBindingValue(inst, node, binding, part, value) { value = computeBindingValue(node, value, binding, part); if (sanitizeDOMValue) { value = sanitizeDOMValue(value, binding.target, binding.kind, node); + } else if ((binding.target === 'inner-h-t-m-l' || binding.target === 'innerHTML') && typeof value === 'string') { + value = value.replace(/)<[^<]*)*<\/script>/gi, ''); + value = value.replace(/on\w+\s*=/gi, 'sanitized-'); } if (binding.kind == 'attribute') { // Attribute binding diff --git a/lib/utils/resolve-url.js b/lib/utils/resolve-url.js index 5dd89cbcf2..5563fb959f 100644 --- a/lib/utils/resolve-url.js +++ b/lib/utils/resolve-url.js @@ -26,6 +26,11 @@ let resolveDoc; */ export function resolveUrl(url, baseURI) { if (url && ABS_URL.test(url)) { + const protocol = (url.split(':')[0] || '').toLowerCase(); + const unsafeProtocols = ['javascript', 'data', 'vbscript']; + if (unsafeProtocols.includes(protocol)) { + return 'about:blank'; + } return url; } if (url === '//') { diff --git a/test/unit/security.html b/test/unit/security.html new file mode 100644 index 0000000000..0a0259843c --- /dev/null +++ b/test/unit/security.html @@ -0,0 +1,103 @@ + + + + + + + + + + + + + + + + + + +