Version in base suite: 1.6.5+dfsg-1+deb12u6 Version in overlay suite: 1.6.5+dfsg-1+deb12u7 Base version: roundcube_1.6.5+dfsg-1+deb12u7 Target version: roundcube_1.6.5+dfsg-1+deb12u8 Base file: /srv/ftp-master.debian.org/ftp/pool/main/r/roundcube/roundcube_1.6.5+dfsg-1+deb12u7.dsc Target file: /srv/ftp-master.debian.org/policy/pool/main/r/roundcube/roundcube_1.6.5+dfsg-1+deb12u8.dsc changelog | 25 + patches/Avoid-dependency-on-new-package-mlocati-ip-lib.patch | 107 +++++++ patches/CVE-2026-35537.patch | 45 ++ patches/CVE-2026-35538/01-b18a8fa8e.patch | 44 ++ patches/CVE-2026-35538/02-6b137adda.patch | 40 ++ patches/CVE-2026-35539.patch | 28 + patches/CVE-2026-35540.patch | 166 +++++++++++ patches/CVE-2026-35541.patch | 35 ++ patches/CVE-2026-35542/01-fde14d01a.patch | 62 ++++ patches/CVE-2026-35542/02-5aba847cb.patch | 46 +++ patches/CVE-2026-35543.patch | 114 +++++++ patches/CVE-2026-35544.patch | 42 ++ patches/CVE-2026-35545.patch | 42 ++ patches/series | 12 14 files changed, 808 insertions(+) dpkg-source: warning: cannot verify inline signature for /srv/release.debian.org/tmp/tmp7a41zlib/roundcube_1.6.5+dfsg-1+deb12u7.dsc: no acceptable signature found dpkg-source: warning: cannot verify inline signature for /srv/release.debian.org/tmp/tmp7a41zlib/roundcube_1.6.5+dfsg-1+deb12u8.dsc: no acceptable signature found diff -Nru roundcube-1.6.5+dfsg/debian/changelog roundcube-1.6.5+dfsg/debian/changelog --- roundcube-1.6.5+dfsg/debian/changelog 2026-02-11 11:05:21.000000000 +0000 +++ roundcube-1.6.5+dfsg/debian/changelog 2026-03-20 18:15:19.000000000 +0000 @@ -1,3 +1,28 @@ +roundcube (1.6.5+dfsg-1+deb12u8) bookworm-security; urgency=high + + * Cherry pick upstream security fixes from v1.6.14 and v1.6.15 (closes: + #1131182, #1132268): + + Fix CVE-2026-35537: Pre-auth arbitrary file write via unsafe + deserialization in redis/memcache session handler. + + Fix CVE-2026-35538: IMAP Injection + CSRF bypass in mail search. + + Fix CVE-2026-35539: XSS vulnerability in HTML attachment preview. + + Fix CVE-2026-35540: SSRF and information disclosure vulnerability via + stylesheet links pointing to a local network hosts. + + Fix CVE-2026-35541: A password could get changed without providing the + old password in some situations. + + Fix CVE-2026-35542: Remote image blocking bypass via a crafted + background attribute. + + Fix CVE-2026-35543: Remote image blocking bypass via various SVG animate + attributes. + + Fix CVE-2026-35544: Fixed position mitigation bypass via use of + `!important`. + + Fix CVE-2026-35545: SVG animate FUNCIRI attribute bypass (remote image + loading via fill/filter/stroke). + * Add custom patch to avoid runtime dependency on mlocati/ip-lib which is + not present in bookworm. + + -- Guilhem Moulin Fri, 20 Mar 2026 19:15:19 +0100 + roundcube (1.6.5+dfsg-1+deb12u7) bookworm-security; urgency=high * Cherry pick upstream security fixes from v1.6.13 (closes: #1127447): diff -Nru roundcube-1.6.5+dfsg/debian/patches/Avoid-dependency-on-new-package-mlocati-ip-lib.patch roundcube-1.6.5+dfsg/debian/patches/Avoid-dependency-on-new-package-mlocati-ip-lib.patch --- roundcube-1.6.5+dfsg/debian/patches/Avoid-dependency-on-new-package-mlocati-ip-lib.patch 1970-01-01 00:00:00.000000000 +0000 +++ roundcube-1.6.5+dfsg/debian/patches/Avoid-dependency-on-new-package-mlocati-ip-lib.patch 2026-03-20 18:15:19.000000000 +0000 @@ -0,0 +1,107 @@ +From: Guilhem Moulin +Date: Fri, 20 Mar 2026 17:34:30 +0100 +Subject: Avoid dependency on new package mlocati/ip-lib + +Which as of today is not present in Debian. The dependency was +introduced in 27ec6cc9cb25e1ef8b4d4ef39ce76d619caa6870 in order to fix a +CVE-2026-35540. While it can be uploaded to sid, we need another +solution to fix the vulnerability for older suites. + +Bug-Debian: https://bugs.debian.org/1131182 +Forwarded: not-needed +--- + program/lib/Roundcube/rcube_utils.php | 45 ++++++++++++++++++++++++----------- + tests/Framework/Utils.php | 6 +++++ + 2 files changed, 37 insertions(+), 14 deletions(-) + +diff --git a/program/lib/Roundcube/rcube_utils.php b/program/lib/Roundcube/rcube_utils.php +index 8ff1db8..c5532be 100644 +--- a/program/lib/Roundcube/rcube_utils.php ++++ b/program/lib/Roundcube/rcube_utils.php +@@ -1,7 +1,5 @@ + contains($address)) { ++ foreach ($nets as [$range_start, $range_end]) { ++ $range_start = @inet_pton($range_start); ++ $range_end = @inet_pton($range_end); ++ if (strcmp($range_start, $address) <= 0 && strcmp($range_end, $address) >= 0) { + return true; + } + } +- + return false; + } + +diff --git a/tests/Framework/Utils.php b/tests/Framework/Utils.php +index 8a95001..1a24826 100644 +--- a/tests/Framework/Utils.php ++++ b/tests/Framework/Utils.php +@@ -571,12 +571,18 @@ class Framework_Utils extends PHPUnit\Framework\TestCase + return [ + // Local hosts + ['https://127.0.0.1', true], ++ ['https://127.00.000.0', true], + ['https://10.1.1.1', true], + ['https://172.16.0.1', true], + ['https://192.168.0.100', true], + ['https://169.254.0.200', true], + ['http://[fc00::1]', true], + ['ftp://[::1]:8080', true], ++ ['https://[127.0.0.1]', true], ++ ['https://[::127.0.0.1]', true], ++ ['https://[::127.0.0.001]', true], ++ ['https://[::ffff:192.168.1.2]', true], ++ ['https://[::ffff:192.168.01.002]', true], + ['//127.0.0.1', true], + ['http://localhost', true], + ['http://localhost.localdomain', true], diff -Nru roundcube-1.6.5+dfsg/debian/patches/CVE-2026-35537.patch roundcube-1.6.5+dfsg/debian/patches/CVE-2026-35537.patch --- roundcube-1.6.5+dfsg/debian/patches/CVE-2026-35537.patch 1970-01-01 00:00:00.000000000 +0000 +++ roundcube-1.6.5+dfsg/debian/patches/CVE-2026-35537.patch 2026-03-20 18:15:19.000000000 +0000 @@ -0,0 +1,45 @@ +From: Aleksander Machniak +Date: Tue, 17 Mar 2026 15:11:38 +0100 +Subject: Fix pre-auth arbitrary file write via unsafe deserialization in + redis/memcache session handler + +Disable GuzzleHttp\Cookie\FileCookieJar instantiation. + +Reported by y0us. + +Origin: https://github.com/roundcube/roundcubemail/commit/a4ead994d2f0ea92e4a1603196a197e0d5df1620 +Bug: https://roundcube.net/news/2026/03/18/security-updates-1.7-rc5-1.6.14-1.5.14 +Bug-Debian: https://bugs.debian.org/1131182 +Bug-Debian-Security: https://security-tracker.debian.org/tracker/CVE-2026-35537 +--- + program/include/iniset.php | 11 ++++++++++- + 1 file changed, 10 insertions(+), 1 deletion(-) + +diff --git a/program/include/iniset.php b/program/include/iniset.php +index c4ab39f..4dc4937 100644 +--- a/program/include/iniset.php ++++ b/program/include/iniset.php +@@ -1,6 +1,8 @@ + +Date: Tue, 17 Mar 2026 15:34:13 +0100 +Subject: Fix IMAP Injection + CSRF bypass in mail search + +Reported by Martila Security Research Team + +Origin: https://github.com/roundcube/roundcubemail/commit/b18a8fa8e81571914c0ff55d4e20edb459c6952c +Bug: https://roundcube.net/news/2026/03/18/security-updates-1.7-rc5-1.6.14-1.5.14 +Bug-Debian: https://bugs.debian.org/1131182 +Bug-Debian-Security: https://security-tracker.debian.org/tracker/CVE-2026-35538 +--- + program/actions/mail/search.php | 4 ++++ + program/actions/mail/send.php | 3 +++ + 2 files changed, 7 insertions(+) + +diff --git a/program/actions/mail/search.php b/program/actions/mail/search.php +index 84b4909..3dac7a5 100644 +--- a/program/actions/mail/search.php ++++ b/program/actions/mail/search.php +@@ -71,6 +71,10 @@ class rcmail_action_mail_search extends rcmail_action_mail_index + $sort_column = self::sort_column(); + $sort_order = self::sort_order(); + ++ // We pass the filter as-is into IMAP SEARCH command. A newline could be used ++ // to inject extra commands, so we remove these. ++ $search_str = preg_replace('/[\r\n]+/', ' ', $search_str); ++ + // set message set for already stored (but incomplete) search request + if (!empty($continue) && isset($_SESSION['search']) && $_SESSION['search_request'] == $continue) { + $rcmail->storage->set_search_set($_SESSION['search']); +diff --git a/program/actions/mail/send.php b/program/actions/mail/send.php +index a28d7f9..0226fdc 100644 +--- a/program/actions/mail/send.php ++++ b/program/actions/mail/send.php +@@ -281,6 +281,9 @@ class rcmail_action_mail_send extends rcmail_action + } + + if ($savedraft) { ++ // Sanitize the IMAP SEARCH input ++ $message_id = preg_replace('/[\r\n]+/', '', $message_id); ++ + // remember new draft-uid ($saved could be an UID or true/false here) + if ($saved && is_bool($saved)) { + $index = $rcmail->storage->search_once($drafts_mbox, 'HEADER Message-ID ' . $message_id); diff -Nru roundcube-1.6.5+dfsg/debian/patches/CVE-2026-35538/02-6b137adda.patch roundcube-1.6.5+dfsg/debian/patches/CVE-2026-35538/02-6b137adda.patch --- roundcube-1.6.5+dfsg/debian/patches/CVE-2026-35538/02-6b137adda.patch 1970-01-01 00:00:00.000000000 +0000 +++ roundcube-1.6.5+dfsg/debian/patches/CVE-2026-35538/02-6b137adda.patch 2026-03-20 18:15:19.000000000 +0000 @@ -0,0 +1,40 @@ +From: Aleksander Machniak +Date: Thu, 19 Mar 2026 14:11:06 +0100 +Subject: Fix regression where mail search would fail on non-ascii search + criteria + +Origin: https://github.com/roundcube/roundcubemail/commit/6b137adda9b042c3742b0f968692e95ed367d3d1 +Bug: https://github.com/roundcube/roundcubemail/issues/10121 +Bug: https://roundcube.net/news/2026/03/18/security-updates-1.7-rc5-1.6.14-1.5.14 +Bug-Debian: https://bugs.debian.org/1131182 +Bug-Debian-Security: https://security-tracker.debian.org/tracker/CVE-2026-35538 +--- + program/actions/mail/search.php | 8 ++++---- + 1 file changed, 4 insertions(+), 4 deletions(-) + +diff --git a/program/actions/mail/search.php b/program/actions/mail/search.php +index 3dac7a5..2525b0f 100644 +--- a/program/actions/mail/search.php ++++ b/program/actions/mail/search.php +@@ -56,6 +56,10 @@ class rcmail_action_mail_search extends rcmail_action_mail_index + // add list filter string + $search_str = $filter && $filter != 'ALL' ? $filter : ''; + ++ // We pass the filter as-is into IMAP SEARCH command. A newline could be used ++ // to inject extra commands, so we remove these. ++ $search_str = preg_replace('/[\r\n]+/', ' ', $search_str); ++ + if ($search_interval = self::search_interval_criteria($interval)) { + $search_str .= ' ' . $search_interval; + } +@@ -71,10 +75,6 @@ class rcmail_action_mail_search extends rcmail_action_mail_index + $sort_column = self::sort_column(); + $sort_order = self::sort_order(); + +- // We pass the filter as-is into IMAP SEARCH command. A newline could be used +- // to inject extra commands, so we remove these. +- $search_str = preg_replace('/[\r\n]+/', ' ', $search_str); +- + // set message set for already stored (but incomplete) search request + if (!empty($continue) && isset($_SESSION['search']) && $_SESSION['search_request'] == $continue) { + $rcmail->storage->set_search_set($_SESSION['search']); diff -Nru roundcube-1.6.5+dfsg/debian/patches/CVE-2026-35539.patch roundcube-1.6.5+dfsg/debian/patches/CVE-2026-35539.patch --- roundcube-1.6.5+dfsg/debian/patches/CVE-2026-35539.patch 1970-01-01 00:00:00.000000000 +0000 +++ roundcube-1.6.5+dfsg/debian/patches/CVE-2026-35539.patch 2026-03-20 18:15:19.000000000 +0000 @@ -0,0 +1,28 @@ +From: Aleksander Machniak +Date: Wed, 18 Mar 2026 10:23:34 +0100 +Subject: Fix XSS issue in a HTML attachment preview + +Reported by aikido_security + +Origin: https://github.com/roundcube/roundcubemail/commit/10a6d1fa8acac85c727b0a6ae4a6642bfa27bea1 +Bug: https://roundcube.net/news/2026/03/18/security-updates-1.7-rc5-1.6.14-1.5.14 +Bug-Debian: https://bugs.debian.org/1131182 +Bug-Debian-Security: https://security-tracker.debian.org/tracker/CVE-2026-35539 +--- + program/include/rcmail_action.php | 3 +++ + 1 file changed, 3 insertions(+) + +diff --git a/program/include/rcmail_action.php b/program/include/rcmail_action.php +index 9cb41da..4266ac1 100644 +--- a/program/include/rcmail_action.php ++++ b/program/include/rcmail_action.php +@@ -691,6 +691,9 @@ abstract class rcmail_action + header('Content-Type: ' . $file['mimetype']); + header('Content-Length: ' . $file['size']); + ++ // Use strict security policy to make sure no javascript is executed ++ header("Content-Security-Policy: script-src 'none'"); ++ + if (isset($file['data']) && is_string($file['data'])) { + echo $file['data']; + } diff -Nru roundcube-1.6.5+dfsg/debian/patches/CVE-2026-35540.patch roundcube-1.6.5+dfsg/debian/patches/CVE-2026-35540.patch --- roundcube-1.6.5+dfsg/debian/patches/CVE-2026-35540.patch 1970-01-01 00:00:00.000000000 +0000 +++ roundcube-1.6.5+dfsg/debian/patches/CVE-2026-35540.patch 2026-03-20 18:15:19.000000000 +0000 @@ -0,0 +1,166 @@ +From: Aleksander Machniak +Date: Wed, 18 Mar 2026 10:35:16 +0100 +Subject: Fix SSRF + Information Disclosure via stylesheet links to a local + network hosts + +Reported by Georgios Tsimpidas (aka Frey), Security Researcher at https://i0.rs/ + +Origin: https://github.com/roundcube/roundcubemail/commit/27ec6cc9cb25e1ef8b4d4ef39ce76d619caa6870 +Bug: https://roundcube.net/news/2026/03/18/security-updates-1.7-rc5-1.6.14-1.5.14 +Bug-Debian: https://bugs.debian.org/1131182 +Bug-Debian-Security: https://security-tracker.debian.org/tracker/CVE-2026-35540 +--- + program/actions/mail/index.php | 2 +- + program/actions/utils/modcss.php | 2 +- + program/lib/Roundcube/rcube_utils.php | 46 ++++++++++++++++++++++++++++++++- + program/lib/Roundcube/rcube_washtml.php | 2 +- + tests/Framework/Utils.php | 34 ++++++++++++++++++++++++ + 5 files changed, 82 insertions(+), 4 deletions(-) + +diff --git a/program/actions/mail/index.php b/program/actions/mail/index.php +index 9c54955..55b3cb4 100644 +--- a/program/actions/mail/index.php ++++ b/program/actions/mail/index.php +@@ -1270,7 +1270,7 @@ class rcmail_action_mail_index extends rcmail_action + if (isset($attrib['href'])) { + $attrib['href'] = preg_replace('/[\x00-\x1F]/', '', $attrib['href']); + +- if ($tag == 'link' && preg_match('/^https?:\/\//i', $attrib['href'])) { ++ if ($tag == 'link' && preg_match('/^https?:\/\//i', $attrib['href']) && !rcube_utils::is_local_url($attrib['href'])) { + $tempurl = 'tmp-' . md5($attrib['href']) . '.css'; + $_SESSION['modcssurls'][$tempurl] = $attrib['href']; + $attrib['href'] = $rcmail->url([ +diff --git a/program/actions/utils/modcss.php b/program/actions/utils/modcss.php +index d1f34b3..8512bdf 100644 +--- a/program/actions/utils/modcss.php ++++ b/program/actions/utils/modcss.php +@@ -44,7 +44,7 @@ class rcmail_action_utils_modcss extends rcmail_action + $ctype = null; + + try { +- $client = rcube::get_instance()->get_http_client(); ++ $client = rcube::get_instance()->get_http_client(['allow_redirects' => false]); + $response = $client->get($realurl); + + if (!empty($response)) { +diff --git a/program/lib/Roundcube/rcube_utils.php b/program/lib/Roundcube/rcube_utils.php +index 59a26c0..8ff1db8 100644 +--- a/program/lib/Roundcube/rcube_utils.php ++++ b/program/lib/Roundcube/rcube_utils.php +@@ -1,6 +1,8 @@ + contains($address)) { ++ return true; ++ } ++ } ++ ++ return false; ++ } ++ ++ // FIXME: Should we accept any non-fqdn hostnames? ++ return (bool) preg_match('/^localhost(\.localdomain)?$/i', $host); ++ } ++ ++ return false; ++ } ++ + /** + * Replace all css definitions with #container [def] + * and remove css-inlined scripting, make position style safe +diff --git a/program/lib/Roundcube/rcube_washtml.php b/program/lib/Roundcube/rcube_washtml.php +index 5b0115b..a2b737c 100644 +--- a/program/lib/Roundcube/rcube_washtml.php ++++ b/program/lib/Roundcube/rcube_washtml.php +@@ -393,7 +393,7 @@ class rcube_washtml + } + + if (preg_match('/^(http|https|ftp):.+/i', $uri)) { +- if (!empty($this->config['allow_remote'])) { ++ if (!empty($this->config['allow_remote']) || rcube_utils::is_local_url($uri)) { + return $uri; + } + +diff --git a/tests/Framework/Utils.php b/tests/Framework/Utils.php +index 9a702d6..8a95001 100644 +--- a/tests/Framework/Utils.php ++++ b/tests/Framework/Utils.php +@@ -552,6 +552,40 @@ class Framework_Utils extends PHPUnit\Framework\TestCase + } + } + ++ /** ++ * Test is_local_url() ++ * ++ * @dataProvider provide_is_local_url_cases ++ */ ++ #[DataProvider('provide_is_local_url_cases')] ++ public function test_is_local_url($input, $output) ++ { ++ $this->assertSame($output, \rcube_utils::is_local_url($input)); ++ } ++ ++ /** ++ * Test-Cases for is_local_url() test ++ */ ++ public static function provide_is_local_url_cases(): iterable ++ { ++ return [ ++ // Local hosts ++ ['https://127.0.0.1', true], ++ ['https://10.1.1.1', true], ++ ['https://172.16.0.1', true], ++ ['https://192.168.0.100', true], ++ ['https://169.254.0.200', true], ++ ['http://[fc00::1]', true], ++ ['ftp://[::1]:8080', true], ++ ['//127.0.0.1', true], ++ ['http://localhost', true], ++ ['http://localhost.localdomain', true], ++ // Non-local hosts ++ ['http://[2001:470::76:0:0:0:2]', false], ++ ['http://domain.tld', false], ++ ]; ++ } ++ + /** + * rcube:utils::strtotime() + */ diff -Nru roundcube-1.6.5+dfsg/debian/patches/CVE-2026-35541.patch roundcube-1.6.5+dfsg/debian/patches/CVE-2026-35541.patch --- roundcube-1.6.5+dfsg/debian/patches/CVE-2026-35541.patch 1970-01-01 00:00:00.000000000 +0000 +++ roundcube-1.6.5+dfsg/debian/patches/CVE-2026-35541.patch 2026-03-20 18:15:19.000000000 +0000 @@ -0,0 +1,35 @@ +From: Aleksander Machniak +Date: Tue, 17 Mar 2026 15:18:24 +0100 +Subject: Fix bug where a password could get changed without providing the old + password + +The password plugin uses loose comparison, leading to a type juggling vulnerability that +allows password changes without knowing the old password in specific cases. + +Reported by flydragon777 + +Origin: https://github.com/roundcube/roundcubemail/commit/6fa2bddc59b9c9fd31cad4a9e2954a208d793dce +Bug: https://roundcube.net/news/2026/03/18/security-updates-1.7-rc5-1.6.14-1.5.14 +Bug-Debian: https://bugs.debian.org/1131182 +Bug-Debian-Security: https://security-tracker.debian.org/tracker/CVE-2026-35541 +--- + plugins/password/password.php | 4 ++-- + 1 file changed, 2 insertions(+), 2 deletions(-) + +diff --git a/plugins/password/password.php b/plugins/password/password.php +index ebde3ec..e4cdd8a 100644 +--- a/plugins/password/password.php ++++ b/plugins/password/password.php +@@ -333,10 +333,10 @@ class password extends rcube_plugin + else { + switch ($type) { + case PASSWORD_COMPARE_CURRENT: +- $result = $curpwd != $newpwd ? $this->gettext('passwordincorrect') : null; ++ $result = $curpwd !== $newpwd ? $this->gettext('passwordincorrect') : null; + break; + case PASSWORD_COMPARE_NEW: +- $result = $curpwd == $newpwd ? $this->gettext('samepasswd') : null; ++ $result = $curpwd === $newpwd ? $this->gettext('samepasswd') : null; + break; + default: + $result = $this->gettext('internalerror'); diff -Nru roundcube-1.6.5+dfsg/debian/patches/CVE-2026-35542/01-fde14d01a.patch roundcube-1.6.5+dfsg/debian/patches/CVE-2026-35542/01-fde14d01a.patch --- roundcube-1.6.5+dfsg/debian/patches/CVE-2026-35542/01-fde14d01a.patch 1970-01-01 00:00:00.000000000 +0000 +++ roundcube-1.6.5+dfsg/debian/patches/CVE-2026-35542/01-fde14d01a.patch 2026-03-20 18:15:19.000000000 +0000 @@ -0,0 +1,62 @@ +From: Aleksander Machniak +Date: Wed, 18 Mar 2026 10:15:43 +0100 +Subject: Fix remote image blocking bypass via a crafted body background + attribute + +Reported by nullcathedral + +Origin: https://github.com/roundcube/roundcubemail/commit/fde14d01adc9f37893cd82b635883e516ed453f8 +Bug: https://roundcube.net/news/2026/03/18/security-updates-1.7-rc5-1.6.14-1.5.14 +Bug-Debian: https://bugs.debian.org/1131182 +Bug-Debian-Security: https://security-tracker.debian.org/tracker/CVE-2026-35542 +--- + program/lib/Roundcube/rcube_washtml.php | 5 +++++ + tests/Framework/Washtml.php | 19 +++++++++++++------ + 2 files changed, 18 insertions(+), 6 deletions(-) + +diff --git a/program/lib/Roundcube/rcube_washtml.php b/program/lib/Roundcube/rcube_washtml.php +index 4e05462..abca35f 100644 +--- a/program/lib/Roundcube/rcube_washtml.php ++++ b/program/lib/Roundcube/rcube_washtml.php +@@ -427,6 +427,11 @@ class rcube_washtml + return 'data:image/' . $type . ',' . base64_encode($svg); + } + ++ // At this point we allow only valid base64 images ++ if (stripos($type, 'base64') === false || preg_match('|[^0-9a-z\s/+]|i', $matches[2])) { ++ return ''; ++ } ++ + return $uri; + } + } +diff --git a/tests/Framework/Washtml.php b/tests/Framework/Washtml.php +index 457e8eb..ff2ad0f 100644 +--- a/tests/Framework/Washtml.php ++++ b/tests/Framework/Washtml.php +@@ -262,12 +262,19 @@ class Framework_Washtml extends PHPUnit\Framework\TestCase + $washer = new rcube_washtml(['html_elements' => ['body']]); + $washed = $washer->wash($html); + +- $this->assertMatchesRegularExpression('|bgcolor="#fff"|', $washed, "Body bgcolor attribute"); +- $this->assertMatchesRegularExpression('|text="#000"|', $washed, "Body text attribute"); +- $this->assertMatchesRegularExpression('|background="#test"|', $washed, "Body background attribute"); +- $this->assertMatchesRegularExpression('|link="#111"|', $washed, "Body link attribute"); +- $this->assertMatchesRegularExpression('|alink="#222"|', $washed, "Body alink attribute"); +- $this->assertMatchesRegularExpression('|vlink="#333"|', $washed, "Body vlink attribute"); ++ $this->assertMatchesRegularExpression('|bgcolor="#fff"|', $washed, 'Body bgcolor attribute'); ++ $this->assertMatchesRegularExpression('|text="#000"|', $washed, 'Body text attribute'); ++ $this->assertMatchesRegularExpression('|background="#test"|', $washed, 'Body background attribute'); ++ $this->assertMatchesRegularExpression('|link="#111"|', $washed, 'Body link attribute'); ++ $this->assertMatchesRegularExpression('|alink="#222"|', $washed, 'Body alink attribute'); ++ $this->assertMatchesRegularExpression('|vlink="#333"|', $washed, 'Body vlink attribute'); ++ ++ $html = ''; ++ ++ $washer = new \rcube_washtml(['html_elements' => ['body']]); ++ $washed = $washer->wash($html); ++ ++ $this->assertMatchesRegularExpression('|x-washed="background"|', $washed, 'Body evil background'); + } + + /** diff -Nru roundcube-1.6.5+dfsg/debian/patches/CVE-2026-35542/02-5aba847cb.patch roundcube-1.6.5+dfsg/debian/patches/CVE-2026-35542/02-5aba847cb.patch --- roundcube-1.6.5+dfsg/debian/patches/CVE-2026-35542/02-5aba847cb.patch 1970-01-01 00:00:00.000000000 +0000 +++ roundcube-1.6.5+dfsg/debian/patches/CVE-2026-35542/02-5aba847cb.patch 2026-03-20 18:15:19.000000000 +0000 @@ -0,0 +1,46 @@ +From: Aleksander Machniak +Date: Sat, 28 Mar 2026 09:28:34 +0100 +Subject: Fix regression where some data url images could get ignored/lost + +Origin: https://github.com/roundcube/roundcubemail/commit/5aba847cb8d5e00a52405e5cd1becb7ec0dcbe4b +Bug: https://github.com/roundcube/roundcubemail/issues/10128 +Bug: https://roundcube.net/news/2026/03/18/security-updates-1.7-rc5-1.6.14-1.5.14 +Bug-Debian: https://bugs.debian.org/1131182 +Bug-Debian-Security: https://security-tracker.debian.org/tracker/CVE-2026-35542 +--- + program/lib/Roundcube/rcube_washtml.php | 2 +- + tests/Framework/Washtml.php | 4 ++-- + 2 files changed, 3 insertions(+), 3 deletions(-) + +diff --git a/program/lib/Roundcube/rcube_washtml.php b/program/lib/Roundcube/rcube_washtml.php +index abca35f..5b0115b 100644 +--- a/program/lib/Roundcube/rcube_washtml.php ++++ b/program/lib/Roundcube/rcube_washtml.php +@@ -428,7 +428,7 @@ class rcube_washtml + } + + // At this point we allow only valid base64 images +- if (stripos($type, 'base64') === false || preg_match('|[^0-9a-z\s/+]|i', $matches[2])) { ++ if (stripos($type, 'base64') === false || preg_match('|[^0-9a-z\s/+=]|i', $matches[2])) { + return ''; + } + +diff --git a/tests/Framework/Washtml.php b/tests/Framework/Washtml.php +index ff2ad0f..920d5ca 100644 +--- a/tests/Framework/Washtml.php ++++ b/tests/Framework/Washtml.php +@@ -54,12 +54,12 @@ class Framework_Washtml extends PHPUnit\Framework\TestCase + */ + function test_data_image_with_newline() + { +- $html = "

"; ++ $html = "

"; + + $washer = new rcube_washtml; + $washed = $washer->wash($html); + +- $this->assertSame("

", $this->cleanupResult($washed)); ++ $this->assertSame("

", $this->cleanupResult($washed)); + } + + /** diff -Nru roundcube-1.6.5+dfsg/debian/patches/CVE-2026-35543.patch roundcube-1.6.5+dfsg/debian/patches/CVE-2026-35543.patch --- roundcube-1.6.5+dfsg/debian/patches/CVE-2026-35543.patch 1970-01-01 00:00:00.000000000 +0000 +++ roundcube-1.6.5+dfsg/debian/patches/CVE-2026-35543.patch 2026-03-20 18:15:19.000000000 +0000 @@ -0,0 +1,114 @@ +From: Aleksander Machniak +Date: Tue, 17 Mar 2026 15:53:29 +0100 +Subject: Fix remote image blocking bypass via various SVG animate attributes + +Reported by nullcathedral + +Origin: https://github.com/roundcube/roundcubemail/commit/39471343ee081ce1d31696c456a2c163462daae3 +Bug: https://roundcube.net/news/2026/03/18/security-updates-1.7-rc5-1.6.14-1.5.14 +Bug-Debian: https://bugs.debian.org/1131182 +Bug-Debian-Security: https://security-tracker.debian.org/tracker/CVE-2026-35543 +--- + program/lib/Roundcube/rcube_washtml.php | 38 +++++++++++++++++++++++++-------- + tests/Framework/Washtml.php | 14 ++++++++++++ + 2 files changed, 43 insertions(+), 9 deletions(-) + +diff --git a/program/lib/Roundcube/rcube_washtml.php b/program/lib/Roundcube/rcube_washtml.php +index 8721fe7..4e05462 100644 +--- a/program/lib/Roundcube/rcube_washtml.php ++++ b/program/lib/Roundcube/rcube_washtml.php +@@ -504,22 +504,22 @@ class rcube_washtml + * Do it in case-insensitive manner. + * + * @param DOMElement $node The element +- * @param string $attr_name The attribute name +- * @param string $attr_value The attribute value to find ++ * @param string $attr_value The attribute value to find (regexp) + * + * @return bool True if the specified attribute exists and has the expected value + */ + 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) { ++ $val = 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) { ++ if ($attr_name === 'attributename') { ++ $val = trim(preg_replace('/^.*:/', '', $val)); ++ } ++ if (preg_match($attr_value, $val)) { + return true; + } + } +@@ -528,6 +528,27 @@ class rcube_washtml + return false; + } + ++ /** ++ * Check if the node is an insecure element ++ * ++ * @param \DOMElement $node ++ */ ++ private static function is_insecure_tag($node) ++ { ++ $tagName = strtolower($node->nodeName); ++ ++ if (!in_array($tagName, ['animate', 'animatecolor', 'set', 'animatetransform'])) { ++ return false; ++ } ++ ++ if (self::attribute_value($node, 'attributeName', '/^href$/i')) { ++ return true; ++ } ++ ++ return self::attribute_value($node, 'attributeName', '/^(mask|cursor)$/i') ++ && self::attribute_value($node, 'values', '/url\(/i'); ++ } ++ + /** + * The main loop that recurse on a node tree. + * It output only allowed tags with allowed attributes and allowed inline styles +@@ -579,10 +600,9 @@ class rcube_washtml + + $node->setAttribute('href', (string) $uri); + } +- else if (in_array($tagName, ['animate', 'animatecolor', 'set', 'animatetransform']) +- && self::attribute_value($node, 'attributename', 'href') +- ) { ++ else if (self::is_insecure_tag($node)) { + // Insecure svg tags ++ // TODO: We really should use wash_attribs()/wash_uri() for these cases + if ($this->config['add_comments']) { + $dump .= ""; + } +diff --git a/tests/Framework/Washtml.php b/tests/Framework/Washtml.php +index ef324f8..457e8eb 100644 +--- a/tests/Framework/Washtml.php ++++ b/tests/Framework/Washtml.php +@@ -500,6 +500,20 @@ class Framework_Washtml extends PHPUnit\Framework\TestCase + '', + '', + ], ++ [ ++ '', ++ '', ++ ], ++ [ ++ '', ++ '', ++ ], ++ [ ++ '', ++ '', ++ ], + ]; + } + diff -Nru roundcube-1.6.5+dfsg/debian/patches/CVE-2026-35544.patch roundcube-1.6.5+dfsg/debian/patches/CVE-2026-35544.patch --- roundcube-1.6.5+dfsg/debian/patches/CVE-2026-35544.patch 1970-01-01 00:00:00.000000000 +0000 +++ roundcube-1.6.5+dfsg/debian/patches/CVE-2026-35544.patch 2026-03-20 18:15:19.000000000 +0000 @@ -0,0 +1,42 @@ +From: Aleksander Machniak +Date: Wed, 18 Mar 2026 10:20:00 +0100 +Subject: Fix fixed position mitigation bypass via use of !important + +Reported by nullcathedral + +Origin: https://github.com/roundcube/roundcubemail/commit/099009b9c8e1d3c636fb9a5af72f7c2596018662 +Bug: https://roundcube.net/news/2026/03/18/security-updates-1.7-rc5-1.6.14-1.5.14 +Bug-Debian: https://bugs.debian.org/1131182 +Bug-Debian-Security: https://security-tracker.debian.org/tracker/CVE-2026-35544 +--- + program/lib/Roundcube/rcube_utils.php | 2 +- + tests/Framework/Utils.php | 3 +++ + 2 files changed, 4 insertions(+), 1 deletion(-) + +diff --git a/program/lib/Roundcube/rcube_utils.php b/program/lib/Roundcube/rcube_utils.php +index d847461..59a26c0 100644 +--- a/program/lib/Roundcube/rcube_utils.php ++++ b/program/lib/Roundcube/rcube_utils.php +@@ -558,7 +558,7 @@ class rcube_utils + if ($property == 'page') { + // Remove 'page' attributes (#7604) + continue; +- } elseif ($property == 'position' && strcasecmp($value, 'fixed') === 0) { ++ } elseif ($property == 'position' && stripos($value, 'fixed') !== false) { + // Convert position:fixed to position:absolute (#5264) + $value = 'absolute'; + } elseif (preg_match('/expression|image-set/i', $value)) { +diff --git a/tests/Framework/Utils.php b/tests/Framework/Utils.php +index c0e9aea..9a702d6 100644 +--- a/tests/Framework/Utils.php ++++ b/tests/Framework/Utils.php +@@ -280,6 +280,9 @@ class Framework_Utils extends PHPUnit\Framework\TestCase + $mod = \rcube_utils::mod_css_styles('.test { position: fixed; top: 0;', 'rcmbody'); + $this->assertSame('#rcmbody .test { position: absolute; top: 0; }', $mod, 'Replace position:fixed with position:absolute (6)'); + ++ $mod = \rcube_utils::mod_css_styles('.test { position: fixed !important; }', 'rcmbody'); ++ $this->assertSame('#rcmbody .test { position: absolute; }', $mod, 'Replace position:fixed with position:absolute (7)'); ++ + // allow data URIs with images (#5580) + $mod = rcube_utils::mod_css_styles("body { background-image: url(data:image/png;base64,123); }", 'rcmbody'); + $this->assertStringContainsString("#rcmbody { background-image: url(data:image/png;base64,123);", $mod, "Data URIs in url() allowed [1]"); diff -Nru roundcube-1.6.5+dfsg/debian/patches/CVE-2026-35545.patch roundcube-1.6.5+dfsg/debian/patches/CVE-2026-35545.patch --- roundcube-1.6.5+dfsg/debian/patches/CVE-2026-35545.patch 1970-01-01 00:00:00.000000000 +0000 +++ roundcube-1.6.5+dfsg/debian/patches/CVE-2026-35545.patch 2026-03-20 18:15:19.000000000 +0000 @@ -0,0 +1,42 @@ +From: Aleksander Machniak +Date: Sun, 29 Mar 2026 11:42:52 +0200 +Subject: Fix SVG Animate FUNCIRI Attribute Bypass — Remote Image Loading via fill/filter/stroke + +Origin: https://github.com/roundcube/roundcubemail/commit/9d18d524f3cc211003fc99e2e54eed09a2f3da88 +Bug: https://roundcube.net/news/2026/03/29/security-updates-1.7-rc6-1.6.15-1.5.15 +Bug-Debian: https://bugs.debian.org/1132268 +Bug-Debian-Security: https://security-tracker.debian.org/tracker/CVE-2026-35545 +--- + program/lib/Roundcube/rcube_washtml.php | 3 ++- + tests/Framework/Washtml.php | 4 ++++ + 2 files changed, 6 insertions(+), 1 deletion(-) + +diff --git a/program/lib/Roundcube/rcube_washtml.php b/program/lib/Roundcube/rcube_washtml.php +index a2b737c..922a5da 100644 +--- a/program/lib/Roundcube/rcube_washtml.php ++++ b/program/lib/Roundcube/rcube_washtml.php +@@ -550,7 +550,8 @@ class rcube_washtml + return true; + } + +- return self::attribute_value($node, 'attributeName', '/^(mask|cursor)$/i') ++ $rx = '/^(mask|cursor|fill|filter|stroke|clip-path|marker-start|marker-end|marker-mid)$/i'; ++ return self::attribute_value($node, 'attributeName', $rx) + && self::attribute_value($node, 'values', '/url\(/i'); + } + +diff --git a/tests/Framework/Washtml.php b/tests/Framework/Washtml.php +index 920d5ca..ec1dd5d 100644 +--- a/tests/Framework/Washtml.php ++++ b/tests/Framework/Washtml.php +@@ -521,6 +521,10 @@ class Framework_Washtml extends PHPUnit\Framework\TestCase + . ' feel="freeze" dur="1s" />', + '', + ], ++ [ ++ '', ++ '', ++ ], + ]; + } + diff -Nru roundcube-1.6.5+dfsg/debian/patches/series roundcube-1.6.5+dfsg/debian/patches/series --- roundcube-1.6.5+dfsg/debian/patches/series 2026-02-11 11:05:21.000000000 +0000 +++ roundcube-1.6.5+dfsg/debian/patches/series 2026-03-20 18:15:19.000000000 +0000 @@ -36,3 +36,15 @@ CVE-2026-26079/01-1f4c3a5af.patch CVE-2026-26079/02-2b5625f1d.patch CVE-2026-26079/03-53d75d5df.patch +CVE-2026-35537.patch +CVE-2026-35541.patch +CVE-2026-35538/01-b18a8fa8e.patch +CVE-2026-35538/02-6b137adda.patch +CVE-2026-35543.patch +CVE-2026-35542/01-fde14d01a.patch +CVE-2026-35542/02-5aba847cb.patch +CVE-2026-35544.patch +CVE-2026-35539.patch +CVE-2026-35540.patch +Avoid-dependency-on-new-package-mlocati-ip-lib.patch +CVE-2026-35545.patch