Fix Cross-Site-Scripting vulnerability via SVG's animate tag

reported by Valentin T., CrowdStrike.
This commit is contained in:
Aleksander Machniak
2025-12-14 09:01:26 +01:00
parent 59700c5ee8
commit 5162a0d9d7
3 changed files with 21 additions and 4 deletions

View File

@@ -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)

View File

@@ -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>
'/(<\/nobr>)(\s+)(<nobr>)/i',
// PHP bug #32547 workaround: remove title tag
// TODO: This is an old libxml2 bug, maybe we could drop this at some point
'/<title[^>]*>.*<\/title>/iU',
// remove <!doctype> 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
'/<html\s[^>]+>/i',
// washtml/DOMDocument cannot handle xml namespaces
// HTML5 parser cannot handler <?xml
// HTML5 parser cannot handle <?xml
'/<\?xml[^>]*>/i',
];

View File

@@ -365,7 +365,7 @@ class WashtmlTest extends TestCase
<!-- foreignobject ignored -->
<set attributeName="onmouseover" x-washed="to" />
<animate attributeName="onunload" x-washed="to" />
<animate attributeName="xlink:href" begin="0" x-washed="from" />
<!-- animate blocked -->
</svg>';
$washer = new \rcube_washtml();
@@ -448,6 +448,14 @@ class WashtmlTest extends TestCase
. '<a id="xss"><text x="20" y="20">XSS</text></a></svg>',
'<svg><!-- set blocked --><a id="xss"><text x="20" y="20">XSS</text></a></svg>',
],
[
'<svg><a class="a"><animate attributeName="xlink:href" values="javascript:alert(1)" /></a></svg>',
'<svg><a class="a"><!-- animate blocked --></a></svg>',
],
[
'<title><html><head><meta><body></title><svg><a class="a"><animate attributeName="xlink:href" values="javascript:alert(1)" /></a></svg>',
'<svg><a class="a"><!-- animate blocked --></a></svg>',
],
[
'<svg><animate xlink:href="#xss" attributename="href" dur="5s" repeatCount="indefinite" keytimes="0;0;1" values="https://portswigger.net?;javascript:alert(1);0" />'
. '<a id="xss"><text x="20" y="20">XSS</text></a></svg>',