From 5162a0d9d7b05728500375611a2fb4fc55844c7c Mon Sep 17 00:00:00 2001 From: Aleksander Machniak Date: Sun, 14 Dec 2025 09:01:26 +0100 Subject: [PATCH] Fix Cross-Site-Scripting vulnerability via SVG's animate tag reported by Valentin T., CrowdStrike. --- CHANGELOG.md | 4 ++++ program/lib/Roundcube/rcube_washtml.php | 11 ++++++++--- tests/Framework/WashtmlTest.php | 10 +++++++++- 3 files changed, 21 insertions(+), 4 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 259b65c88..83edc4033 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -4,6 +4,10 @@ This file includes only changes we consider noteworthy for users, admins and plu ## Unreleased +- Fix Cross-Site-Scripting vulnerability via SVG's animate tag + +## 1.7-rc + - Move autocomplete list rendering to client-side (#9832) - Remove `contact_search_name` option in favor of `contactlist_name_template` (#9832) - Add scope parameter to contact search (#9863) diff --git a/program/lib/Roundcube/rcube_washtml.php b/program/lib/Roundcube/rcube_washtml.php index bb71a0b7f..30fd73ac9 100644 --- a/program/lib/Roundcube/rcube_washtml.php +++ b/program/lib/Roundcube/rcube_washtml.php @@ -301,6 +301,7 @@ class rcube_washtml // in SVG to/from attribs may contain anything, including URIs if ($key == 'to' || $key == 'from') { $key = strtolower((string) $node->getAttribute('attributeName')); + $key = trim(preg_replace('/^.*:/', '', $key)); if ($key && !isset($this->_html_attribs[$key])) { $key = null; } @@ -505,10 +506,14 @@ class rcube_washtml private static function attribute_value($node, $attr_name, $attr_value) { $attr_name = strtolower($attr_name); + $attr_value = strtolower($attr_value); foreach ($node->attributes as $name => $attr) { if (strtolower($name) === $attr_name) { - if (strtolower($attr_value) === strtolower(trim($attr->nodeValue))) { + // Read the attribute name, remove the namespace (e.g. xlink:href => href) + $val = strtolower(trim($attr->nodeValue)); + $val = trim(preg_replace('/^.*:/', '', $val)); + if ($attr_value === $val) { return true; } } @@ -738,6 +743,7 @@ class rcube_washtml // space(s) between '/(<\/nobr>)(\s+)()/i', // PHP bug #32547 workaround: remove title tag + // TODO: This is an old libxml2 bug, maybe we could drop this at some point '/]*>.*<\/title>/iU', // remove before BOM (#1490291) '/<\!doctype[^>]+>[^<]*/im', @@ -745,8 +751,7 @@ class rcube_washtml '/^(\0\0\xFE\xFF|\xFF\xFE\0\0|\xFE\xFF|\xFF\xFE|\xEF\xBB\xBF)/', // washtml/DOMDocument cannot handle xml namespaces '/]+>/i', - // washtml/DOMDocument cannot handle xml namespaces - // HTML5 parser cannot handler ]*>/i', ]; diff --git a/tests/Framework/WashtmlTest.php b/tests/Framework/WashtmlTest.php index d80ba9af7..df8ad948c 100644 --- a/tests/Framework/WashtmlTest.php +++ b/tests/Framework/WashtmlTest.php @@ -365,7 +365,7 @@ class WashtmlTest extends TestCase - + '; $washer = new \rcube_washtml(); @@ -448,6 +448,14 @@ class WashtmlTest extends TestCase . 'XSS', 'XSS', ], + [ + '', + '', + ], + [ + '<html><head><meta><body>', + '', + ], [ '' . 'XSS',