[Pkg-roundcube-maintainers] Bug#1127447: roundcube: CSS injection vulnerability and remote image blocking bypass
Guilhem Moulin
guilhem at debian.org
Wed Feb 11 11:43:35 GMT 2026
Control: retitle -1 roundcube: [CVE-2026-26079] CSS injection vulnerability and [CVE-2026-25916] remote image blocking bypass
Hi,
Thanks for the update! Here are tested debdiffs for trixie-security and
bookworm-security. As for the previous upload, I suggest to follow
1.6.x for trixie-security (the upstream diff [0] is pretty targeted already)
and backport targeted fixes for bookworm-security.
Cheers
--
Guilhem.
[0] https://github.com/roundcube/roundcubemail/compare/1.6.12...1.6.13
-------------- next part --------------
diffstat for roundcube-1.6.12+dfsg roundcube-1.6.13+dfsg
CHANGELOG.md | 6
debian/changelog | 9
debian/patches/Fix-FTBFS-with-phpunit-11.patch | 121 ++++------
plugins/managesieve/Changelog | 1
plugins/managesieve/lib/Roundcube/rcube_sieve_vacation.php | 8
program/lib/Roundcube/rcube_utils.php | 64 +++--
program/lib/Roundcube/rcube_washtml.php | 3
public_html/plugins/managesieve/Changelog | 1
public_html/plugins/managesieve/lib/Roundcube/rcube_sieve_vacation.php | 8
tests/Framework/Utils.php | 16 +
tests/Framework/Washtml.php | 8
11 files changed, 160 insertions(+), 85 deletions(-)
diff -Nru roundcube-1.6.12+dfsg/CHANGELOG.md roundcube-1.6.13+dfsg/CHANGELOG.md
--- roundcube-1.6.12+dfsg/CHANGELOG.md 2025-12-14 09:10:51.000000000 +0100
+++ roundcube-1.6.13+dfsg/CHANGELOG.md 2026-02-08 10:25:02.000000000 +0100
@@ -2,6 +2,12 @@
## Unreleased
+- Managesieve: Fix handling of string-list format values for date tests in Out of Office (#10075)
+- Fix remote image blocking bypass via SVG content reported by nullcathedral
+- Fix CSS injection vulnerability reported by CERT Polska
+
+## Release 1.6.12
+
- Support IPv6 in database DSN (#9937)
- Don't force specific error_reporting setting
- Fix compatibility with PHP 8.5 regarding array_first()
diff -Nru roundcube-1.6.12+dfsg/debian/changelog roundcube-1.6.13+dfsg/debian/changelog
--- roundcube-1.6.12+dfsg/debian/changelog 2025-12-14 11:51:43.000000000 +0100
+++ roundcube-1.6.13+dfsg/debian/changelog 2026-02-11 10:55:46.000000000 +0100
@@ -1,3 +1,12 @@
+roundcube (1.6.13+dfsg-0+deb13u1) trixie-security; urgency=high
+
+ * New upstream security and bugfix release (closes: #1127447).
+ + Fix CVE-2026-26079: CSS injection vulnerability.
+ + Fix CVE-2026-25916: Remote image blocking bypass via SVG content.
+ * Refresh d/patches.
+
+ -- Guilhem Moulin <guilhem at debian.org> Wed, 11 Feb 2026 10:55:46 +0100
+
roundcube (1.6.12+dfsg-0+deb13u1) trixie-security; urgency=high
* New upstream security and bugfix release (closes: #1122899).
diff -Nru roundcube-1.6.12+dfsg/debian/patches/Fix-FTBFS-with-phpunit-11.patch roundcube-1.6.13+dfsg/debian/patches/Fix-FTBFS-with-phpunit-11.patch
--- roundcube-1.6.12+dfsg/debian/patches/Fix-FTBFS-with-phpunit-11.patch 2025-12-14 11:51:43.000000000 +0100
+++ roundcube-1.6.13+dfsg/debian/patches/Fix-FTBFS-with-phpunit-11.patch 2026-02-11 10:55:46.000000000 +0100
@@ -41,7 +41,7 @@
plugins/managesieve/tests/Forward.php | 16 +-
plugins/managesieve/tests/Managesieve.php | 14 +-
plugins/managesieve/tests/Script.php | 17 +-
- plugins/managesieve/tests/Vacation.php | 21 +-
+ plugins/managesieve/tests/Vacation.php | 21 ++-
plugins/markasjunk/tests/Markasjunk.php | 22 ++-
plugins/new_user_dialog/tests/NewUserDialog.php | 14 +-
.../new_user_identity/tests/NewUserIdentity.php | 14 +-
@@ -76,9 +76,9 @@
tests/Actions/Contacts/Qrcode.php | 17 +-
tests/Actions/Contacts/Save.php | 27 +--
tests/Actions/Contacts/Search.php | 18 +-
- tests/Actions/Contacts/SearchCreate.php | 21 +-
- tests/Actions/Contacts/SearchDelete.php | 21 +-
- tests/Actions/Contacts/Show.php | 21 +-
+ tests/Actions/Contacts/SearchCreate.php | 21 ++-
+ tests/Actions/Contacts/SearchDelete.php | 21 ++-
+ tests/Actions/Contacts/Show.php | 21 ++-
tests/Actions/Contacts/Undo.php | 15 +-
tests/Actions/Contacts/UploadPhoto.php | 19 +-
tests/Actions/Login/Oauth.php | 14 +-
@@ -149,7 +149,7 @@
tests/ExitException.php | 6 +-
tests/Framework/Addressbook.php | 40 ++--
tests/Framework/Addresses.php | 16 +-
- tests/Framework/BaseReplacer.php | 21 +-
+ tests/Framework/BaseReplacer.php | 21 ++-
tests/Framework/Bootstrap.php | 8 +-
tests/Framework/Browser.php | 34 ++--
tests/Framework/Cache.php | 18 +-
@@ -201,7 +201,7 @@
tests/Framework/Text2Html.php | 22 ++-
tests/Framework/TnefDecoder.php | 16 +-
tests/Framework/User.php | 30 +--
- tests/Framework/Utils.php | 211 +++++++++++----------
+ tests/Framework/Utils.php | 209 +++++++++++----------
tests/Framework/VCard.php | 40 ++--
tests/Framework/Washtml.php | 85 +++++----
tests/OutputHtmlMock.php | 6 +-
@@ -221,8 +221,8 @@
tests/Rcmail/Utils.php | 22 ++-
tests/StderrMock.php | 15 +-
tests/StorageMock.php | 4 +-
- tests/bootstrap.php | 21 +-
- 213 files changed, 2503 insertions(+), 1797 deletions(-)
+ tests/bootstrap.php | 21 ++-
+ 213 files changed, 2502 insertions(+), 1796 deletions(-)
diff --git a/plugins/acl/tests/Acl.php b/plugins/acl/tests/Acl.php
index 94e0bd4..0ad987f 100644
@@ -10006,7 +10006,7 @@
$idents = $user->list_identities();
diff --git a/tests/Framework/Utils.php b/tests/Framework/Utils.php
-index 29df81d..cf76834 100644
+index e65b5a9..8809da2 100644
--- a/tests/Framework/Utils.php
+++ b/tests/Framework/Utils.php
@@ -1,11 +1,15 @@
@@ -10177,7 +10177,7 @@
$this->assertSame('/* evil! */', $mod);
$mod = \rcube_utils::mod_css_styles("@\\69mport url('http://localhost/somestuff/css/master.css');", 'rcmbody');
-@@ -261,47 +270,47 @@ class Framework_Utils extends PHPUnit\Framework\TestCase
+@@ -261,19 +270,19 @@ class Framework_Utils extends PHPUnit\Framework\TestCase
$this->assertSame('#rcmbody p { background: none !important; }', $mod);
// position: fixed (#5264)
@@ -10202,6 +10202,10 @@
+ $mod = \rcube_utils::mod_css_styles(".test { position\n: fixed; top: 0; }", 'rcmbody');
$this->assertEquals("#rcmbody .test { position: absolute; top: 0; }", $mod, "Replace position:fixed with position:absolute (5)");
+ // missing closing brace
+@@ -281,27 +290,27 @@ class Framework_Utils extends PHPUnit\Framework\TestCase
+ $this->assertSame('#rcmbody .test { position: absolute; top: 0; }', $mod, 'Replace position:fixed with position:absolute (6)');
+
// allow data URIs with images (#5580)
- $mod = rcube_utils::mod_css_styles("body { background-image: url(data:image/png;base64,123); }", 'rcmbody');
+ $mod = \rcube_utils::mod_css_styles("body { background-image: url(data:image/png;base64,123); }", 'rcmbody');
@@ -10232,13 +10236,8 @@
+ $mod = \rcube_utils::mod_css_styles($style, 'rcmbody', true);
$this->assertSame("#rcmbody { color: red; }", $mod);
- $style = "body { background:url(alert('URL!')); }";
-- $mod = rcube_utils::mod_css_styles($style, 'rcmbody', true);
-+ $mod = \rcube_utils::mod_css_styles($style, 'rcmbody', true);
- $this->assertSame("#rcmbody {}", $mod);
- }
-
-@@ -325,7 +334,7 @@ class Framework_Utils extends PHPUnit\Framework\TestCase
+ $style = 'body { background:url(alert('URL!')); }';
+@@ -335,7 +344,7 @@ class Framework_Utils extends PHPUnit\Framework\TestCase
:root * { color: red; }
:root > * { top: 0; }
';
@@ -10247,7 +10246,7 @@
$this->assertStringContainsString('#rc .testone', $mod);
$this->assertStringContainsString('#rc .testthree.testfour', $mod);
-@@ -343,24 +352,24 @@ class Framework_Utils extends PHPUnit\Framework\TestCase
+@@ -353,24 +362,24 @@ class Framework_Utils extends PHPUnit\Framework\TestCase
function test_xss_entity_decode()
{
@@ -10277,7 +10276,7 @@
{
return [
[
-@@ -435,9 +444,10 @@ class Framework_Utils extends PHPUnit\Framework\TestCase
+@@ -445,9 +454,10 @@ class Framework_Utils extends PHPUnit\Framework\TestCase
*
* @dataProvider data_parse_css_block
*/
@@ -10289,7 +10288,7 @@
}
/**
-@@ -452,7 +462,7 @@ class Framework_Utils extends PHPUnit\Framework\TestCase
+@@ -462,7 +472,7 @@ class Framework_Utils extends PHPUnit\Framework\TestCase
];
foreach ($data as $text => $res) {
@@ -10298,7 +10297,7 @@
$this->assertSame($res, $result);
}
}
-@@ -465,7 +475,7 @@ class Framework_Utils extends PHPUnit\Framework\TestCase
+@@ -475,7 +485,7 @@ class Framework_Utils extends PHPUnit\Framework\TestCase
$data = ['', 'a,b,c', 'a', ',', ',a'];
foreach ($data as $text) {
@@ -10307,7 +10306,7 @@
$this->assertSame(explode(',', $text), $result);
}
}
-@@ -480,7 +490,7 @@ class Framework_Utils extends PHPUnit\Framework\TestCase
+@@ -490,7 +500,7 @@ class Framework_Utils extends PHPUnit\Framework\TestCase
];
foreach ($input as $idx => $value) {
@@ -10316,7 +10315,7 @@
}
$input = [
-@@ -488,7 +498,7 @@ class Framework_Utils extends PHPUnit\Framework\TestCase
+@@ -498,7 +508,7 @@ class Framework_Utils extends PHPUnit\Framework\TestCase
];
foreach ($input as $idx => $value) {
@@ -10325,7 +10324,7 @@
}
}
-@@ -498,13 +508,13 @@ class Framework_Utils extends PHPUnit\Framework\TestCase
+@@ -508,13 +518,13 @@ class Framework_Utils extends PHPUnit\Framework\TestCase
function test_get_input_string()
{
$_GET = [];
@@ -10342,7 +10341,7 @@
}
/**
-@@ -512,18 +522,18 @@ class Framework_Utils extends PHPUnit\Framework\TestCase
+@@ -522,18 +532,18 @@ class Framework_Utils extends PHPUnit\Framework\TestCase
*/
function test_is_simple_string()
{
@@ -10373,7 +10372,7 @@
}
/**
-@@ -538,7 +548,7 @@ class Framework_Utils extends PHPUnit\Framework\TestCase
+@@ -548,7 +558,7 @@ class Framework_Utils extends PHPUnit\Framework\TestCase
];
foreach ($test as $v) {
@@ -10382,7 +10381,7 @@
$this->assertSame($v[2], $result);
}
}
-@@ -568,7 +578,7 @@ class Framework_Utils extends PHPUnit\Framework\TestCase
+@@ -578,7 +588,7 @@ class Framework_Utils extends PHPUnit\Framework\TestCase
];
foreach ($test as $datetime => $ts) {
@@ -10391,7 +10390,7 @@
$this->assertSame($ts, $result, "Error parsing date: $datetime");
}
}
-@@ -595,7 +605,7 @@ class Framework_Utils extends PHPUnit\Framework\TestCase
+@@ -605,7 +615,7 @@ class Framework_Utils extends PHPUnit\Framework\TestCase
];
foreach ($test as $datetime => $ts) {
@@ -10400,7 +10399,7 @@
$this->assertSame($ts, $result ? $result->format('Y-m-d') : false, "Error parsing date: $datetime");
}
-@@ -605,7 +615,7 @@ class Framework_Utils extends PHPUnit\Framework\TestCase
+@@ -615,7 +625,7 @@ class Framework_Utils extends PHPUnit\Framework\TestCase
];
foreach ($test as $datetime => $ts) {
@@ -10409,7 +10408,7 @@
$this->assertSame($ts, $result ? $result->format('Y-m-d H:i:s') : false, "Error parsing date: $datetime");
}
-@@ -614,7 +624,7 @@ class Framework_Utils extends PHPUnit\Framework\TestCase
+@@ -624,7 +634,7 @@ class Framework_Utils extends PHPUnit\Framework\TestCase
];
foreach ($test as $datetime => $ts) {
@@ -10418,7 +10417,7 @@
$this->assertSame($ts, $result ? $result->format('Y-m-d H:i:s O') : false, "Error parsing date: $datetime");
}
}
-@@ -624,17 +634,17 @@ class Framework_Utils extends PHPUnit\Framework\TestCase
+@@ -634,17 +644,17 @@ class Framework_Utils extends PHPUnit\Framework\TestCase
*/
function test_anytodatetime_timezone()
{
@@ -10439,7 +10438,7 @@
if ($result) $result->setTimezone($tz); // move to target timezone for comparison
$this->assertSame($ts, $result ? $result->format('Y-m-d H:i') : false, "Error parsing date: $datetime");
}
-@@ -653,7 +663,7 @@ class Framework_Utils extends PHPUnit\Framework\TestCase
+@@ -663,7 +673,7 @@ class Framework_Utils extends PHPUnit\Framework\TestCase
];
foreach ($test as $data) {
@@ -10448,7 +10447,7 @@
$this->assertSame($data[2], $result, "Error formatting date: " . $data[0]);
}
}
-@@ -672,7 +682,7 @@ class Framework_Utils extends PHPUnit\Framework\TestCase
+@@ -682,7 +692,7 @@ class Framework_Utils extends PHPUnit\Framework\TestCase
];
foreach ($test as $input => $output) {
@@ -10457,7 +10456,7 @@
$this->assertSame($output, $result);
}
}
-@@ -697,7 +707,7 @@ class Framework_Utils extends PHPUnit\Framework\TestCase
+@@ -707,7 +717,7 @@ class Framework_Utils extends PHPUnit\Framework\TestCase
];
foreach ($test as $input => $output) {
@@ -10466,7 +10465,7 @@
$this->assertSame($output, $result, "Error normalizing '$input'");
}
}
-@@ -720,7 +730,7 @@ class Framework_Utils extends PHPUnit\Framework\TestCase
+@@ -730,7 +740,7 @@ class Framework_Utils extends PHPUnit\Framework\TestCase
];
foreach ($test as $idx => $params) {
@@ -10475,7 +10474,7 @@
$this->assertSame($params[2], $result, "words_match() at index $idx");
}
}
-@@ -746,7 +756,7 @@ class Framework_Utils extends PHPUnit\Framework\TestCase
+@@ -756,7 +766,7 @@ class Framework_Utils extends PHPUnit\Framework\TestCase
}
foreach ($test as $input => $output) {
@@ -10484,7 +10483,7 @@
$this->assertSame($output, $result);
}
}
-@@ -756,17 +766,17 @@ class Framework_Utils extends PHPUnit\Framework\TestCase
+@@ -766,17 +776,17 @@ class Framework_Utils extends PHPUnit\Framework\TestCase
*/
function test_random_bytes()
{
@@ -10508,7 +10507,7 @@
{
/*
-@@ -803,9 +813,10 @@ class Framework_Utils extends PHPUnit\Framework\TestCase
+@@ -813,9 +823,10 @@ class Framework_Utils extends PHPUnit\Framework\TestCase
* @param string $encoded Encoded email address
* @dataProvider data_idn_convert
*/
@@ -10520,7 +10519,7 @@
}
/**
-@@ -815,9 +826,10 @@ class Framework_Utils extends PHPUnit\Framework\TestCase
+@@ -825,9 +836,10 @@ class Framework_Utils extends PHPUnit\Framework\TestCase
* @param string $encoded Encoded email address
* @dataProvider data_idn_convert
*/
@@ -10532,7 +10531,7 @@
}
/**
-@@ -825,14 +837,14 @@ class Framework_Utils extends PHPUnit\Framework\TestCase
+@@ -835,14 +847,14 @@ class Framework_Utils extends PHPUnit\Framework\TestCase
*/
function test_idn_to_ascii_special()
{
@@ -10550,7 +10549,7 @@
{
return [
['%z', 'hostname', 'hostname'],
-@@ -847,15 +859,16 @@ class Framework_Utils extends PHPUnit\Framework\TestCase
+@@ -857,15 +869,16 @@ class Framework_Utils extends PHPUnit\Framework\TestCase
*
* @dataProvider data_parse_host
*/
@@ -10569,7 +10568,7 @@
{
return [
[['hostname', null, null], ['hostname', null, null]],
-@@ -878,15 +891,16 @@ class Framework_Utils extends PHPUnit\Framework\TestCase
+@@ -888,15 +901,16 @@ class Framework_Utils extends PHPUnit\Framework\TestCase
*
* @dataProvider data_parse_host_uri
*/
@@ -10588,7 +10587,7 @@
return [
['both', 'Fwd: Re: Test subject both', 'Test subject both'],
['both', 'Re: Fwd: Test subject both', 'Test subject both'],
-@@ -904,8 +918,9 @@ class Framework_Utils extends PHPUnit\Framework\TestCase
+@@ -914,8 +928,9 @@ class Framework_Utils extends PHPUnit\Framework\TestCase
*
* @dataProvider data_remove_subject_prefix
*/
@@ -10599,7 +10598,7 @@
}
/**
-@@ -913,13 +928,13 @@ class Framework_Utils extends PHPUnit\Framework\TestCase
+@@ -923,13 +938,13 @@ class Framework_Utils extends PHPUnit\Framework\TestCase
*/
function test_server_name()
{
@@ -10616,7 +10615,7 @@
}
/**
-@@ -929,31 +944,31 @@ class Framework_Utils extends PHPUnit\Framework\TestCase
+@@ -939,31 +954,31 @@ class Framework_Utils extends PHPUnit\Framework\TestCase
{
$_SERVER['test'] = 'test.com';
@@ -10815,7 +10814,7 @@
$this->assertSame($result, "BEGIN:VCARD\r\nVERSION:3.0\r\nFN:\r\nN:;;;;\r\nEND:VCARD");
diff --git a/tests/Framework/Washtml.php b/tests/Framework/Washtml.php
-index 0b9e1e9..a3a6d5b 100644
+index ef324f8..e8e5a4a 100644
--- a/tests/Framework/Washtml.php
+++ b/tests/Framework/Washtml.php
@@ -1,11 +1,14 @@
@@ -11016,7 +11015,7 @@
{
$svg1 = "<svg id='x' width='100' height='100'><a xlink:href='javascript:alert(1)'><rect x='0' y='0' width='100' height='100' /></a></svg>";
-@@ -500,9 +503,10 @@ class Framework_Washtml extends PHPUnit\Framework\TestCase
+@@ -508,9 +511,10 @@ class Framework_Washtml extends PHPUnit\Framework\TestCase
*
* @dataProvider data_wash_svg_tests
*/
@@ -11028,7 +11027,7 @@
$washed = $washer->wash($input);
$this->assertSame($expected, $this->cleanupResult($washed), "SVG content");
-@@ -511,7 +515,7 @@ class Framework_Washtml extends PHPUnit\Framework\TestCase
+@@ -519,7 +523,7 @@ class Framework_Washtml extends PHPUnit\Framework\TestCase
/**
* Test cases for various XSS issues
*/
@@ -11037,7 +11036,7 @@
{
return [
[
-@@ -566,9 +570,10 @@ class Framework_Washtml extends PHPUnit\Framework\TestCase
+@@ -574,9 +578,10 @@ class Framework_Washtml extends PHPUnit\Framework\TestCase
*
* @dataProvider data_wash_xss_tests
*/
@@ -11049,7 +11048,7 @@
$washed = $washer->wash($input);
$this->assertSame($expected, $this->cleanupResult($washed), "XSS issues");
-@@ -582,7 +587,7 @@ class Framework_Washtml extends PHPUnit\Framework\TestCase
+@@ -590,7 +595,7 @@ class Framework_Washtml extends PHPUnit\Framework\TestCase
$html = "<img style='position:fixed' /><img style=\"position:/**/ fixed; top:10px\" />";
$exp = "<img style=\"position: absolute\" /><img style=\"position: absolute; top: 10px\" />";
@@ -11058,7 +11057,7 @@
$washed = $washer->wash($html);
$this->assertTrue(strpos($washed, $exp) !== false, "Position:fixed (#5264)");
-@@ -626,7 +631,7 @@ class Framework_Washtml extends PHPUnit\Framework\TestCase
+@@ -634,7 +639,7 @@ class Framework_Washtml extends PHPUnit\Framework\TestCase
<annotation encoding="TeX">I_D = \frac{1}{2} k_n \frac{W}{L} (V_{GS}-V_t)^2</annotation>
</semantics></math>';
@@ -11067,7 +11066,7 @@
$washed = $washer->wash($mathml);
// remove whitespace between tags
-@@ -643,7 +648,7 @@ class Framework_Washtml extends PHPUnit\Framework\TestCase
+@@ -651,7 +656,7 @@ class Framework_Washtml extends PHPUnit\Framework\TestCase
{
$html = "<input type=\"image\" src=\"http://TRACKING_URL/\">";
@@ -11076,7 +11075,7 @@
$washed = $washer->wash($html);
$this->assertTrue($washer->extlinks);
-@@ -651,7 +656,7 @@ class Framework_Washtml extends PHPUnit\Framework\TestCase
+@@ -659,7 +664,7 @@ class Framework_Washtml extends PHPUnit\Framework\TestCase
$html = "<video src=\"http://TRACKING_URL/\">";
@@ -11085,7 +11084,7 @@
$washed = $washer->wash($html);
$this->assertTrue($washer->extlinks);
-@@ -672,14 +677,14 @@ class Framework_Washtml extends PHPUnit\Framework\TestCase
+@@ -680,14 +685,14 @@ class Framework_Washtml extends PHPUnit\Framework\TestCase
];
foreach ($html as $item) {
@@ -11102,7 +11101,7 @@
$washed = $washer->wash($item[0]);
$this->assertFalse($washer->extlinks);
-@@ -690,7 +695,7 @@ class Framework_Washtml extends PHPUnit\Framework\TestCase
+@@ -698,7 +703,7 @@ class Framework_Washtml extends PHPUnit\Framework\TestCase
{
$html = '<textarea><p style="x:</textarea><img src=x onerror=alert(1)>">';
@@ -11111,7 +11110,7 @@
$washed = $washer->wash($html);
$this->assertStringNotContainsString('onerror=alert(1)>', $washed);
-@@ -702,7 +707,7 @@ class Framework_Washtml extends PHPUnit\Framework\TestCase
+@@ -710,7 +715,7 @@ class Framework_Washtml extends PHPUnit\Framework\TestCase
*/
function test_css_prefix()
{
@@ -11120,7 +11119,7 @@
$html = '<p id="my-id">'
. '<label for="my-other-id" class="my-class1 my-class2">test</label>'
-@@ -730,14 +735,14 @@ class Framework_Washtml extends PHPUnit\Framework\TestCase
+@@ -738,14 +743,14 @@ class Framework_Washtml extends PHPUnit\Framework\TestCase
{
$html = '<p><?xml:namespace prefix = "xsl" /></p>';
@@ -11137,7 +11136,7 @@
$washed = $this->cleanupResult($washer->wash($html));
$this->assertSame($washed, 'HTML');
-@@ -748,7 +753,7 @@ class Framework_Washtml extends PHPUnit\Framework\TestCase
+@@ -756,7 +761,7 @@ class Framework_Washtml extends PHPUnit\Framework\TestCase
*/
function test_missing_tags()
{
@@ -11146,7 +11145,7 @@
$html = '<head></head>First line<br />Second line';
$washed = $washer->wash($html);
-@@ -790,7 +795,7 @@ class Framework_Washtml extends PHPUnit\Framework\TestCase
+@@ -798,7 +803,7 @@ class Framework_Washtml extends PHPUnit\Framework\TestCase
{
$html = '<p><![CDATA[<script>alert(document.cookie)</script>]]></p>';
@@ -11155,7 +11154,7 @@
$washed = $washer->wash($html);
$this->assertTrue(strpos($washed, '<script>') === false, "CDATA content");
-@@ -802,7 +807,7 @@ class Framework_Washtml extends PHPUnit\Framework\TestCase
+@@ -810,7 +815,7 @@ class Framework_Washtml extends PHPUnit\Framework\TestCase
function test_resolve_base()
{
$html = file_get_contents(TESTS_DIR . 'src/htmlbase.txt');
@@ -11164,7 +11163,7 @@
$this->assertMatchesRegularExpression('|src="http://alec\.pl/dir/img1\.gif"|', $html, "URI base resolving [1]");
$this->assertMatchesRegularExpression('|src="http://alec\.pl/dir/img2\.gif"|', $html, "URI base resolving [2]");
-@@ -848,7 +853,7 @@ class Framework_Washtml extends PHPUnit\Framework\TestCase
+@@ -856,7 +861,7 @@ class Framework_Washtml extends PHPUnit\Framework\TestCase
<tr><td></td></tr>
</table>';
diff -Nru roundcube-1.6.12+dfsg/plugins/managesieve/Changelog roundcube-1.6.13+dfsg/plugins/managesieve/Changelog
--- roundcube-1.6.12+dfsg/plugins/managesieve/Changelog 2025-12-14 09:10:51.000000000 +0100
+++ roundcube-1.6.13+dfsg/plugins/managesieve/Changelog 2026-02-08 10:25:02.000000000 +0100
@@ -1,3 +1,4 @@
+- Fix handling of string-list format values for date tests in Out of Office (#10075)
- Fix invalid line break characters in multi-line text in Sieve scripts (#9543)
- Fix javascript error when relational or spamtest extension is not enabled (#9139)
- Removed managesieve_usetls option (in favor of the scheme prefix in managesieve_host)
diff -Nru roundcube-1.6.12+dfsg/plugins/managesieve/lib/Roundcube/rcube_sieve_vacation.php roundcube-1.6.13+dfsg/plugins/managesieve/lib/Roundcube/rcube_sieve_vacation.php
--- roundcube-1.6.12+dfsg/plugins/managesieve/lib/Roundcube/rcube_sieve_vacation.php 2025-12-14 09:10:51.000000000 +0100
+++ roundcube-1.6.13+dfsg/plugins/managesieve/lib/Roundcube/rcube_sieve_vacation.php 2026-02-08 10:25:02.000000000 +0100
@@ -150,6 +150,14 @@
}
}
+ // According to RFC5260, currentdate target can be a string-list,
+ // but here we support only a single value (#10074)
+ foreach ($rule['tests'] as $i => $r) {
+ if ($r['test'] == 'currentdate' && is_array($r['arg'])) {
+ $rule['tests'][$i]['arg'] = array_first($r['arg']);
+ }
+ }
+
$this->vacation = array_merge($rule['actions'][0], [
'idx' => $idx,
'disabled' => $rule['disabled'] || !$active,
diff -Nru roundcube-1.6.12+dfsg/program/lib/Roundcube/rcube_utils.php roundcube-1.6.13+dfsg/program/lib/Roundcube/rcube_utils.php
--- roundcube-1.6.12+dfsg/program/lib/Roundcube/rcube_utils.php 2025-12-14 09:10:51.000000000 +0100
+++ roundcube-1.6.13+dfsg/program/lib/Roundcube/rcube_utils.php 2026-02-08 10:25:02.000000000 +0100
@@ -432,7 +432,7 @@
*/
public static function mod_css_styles($source, $container_id, $allow_remote = false, $prefix = '')
{
- $source = self::xss_entity_decode($source);
+ $source = self::xss_entity_decode($source);
// No @import allowed
// TODO: We should just remove it, not invalidate the whole content
@@ -445,6 +445,9 @@
return '/* invalid! */';
}
+ // remove html and css comments
+ $source = preg_replace('/(^\s*<\!--)|(-->\s*$)/m', '', $source);
+
// To prevent from a double-escaping tricks we consider a script with
// any escape sequences (after de-escaping them above) an evil script.
// This probably catches many valid scripts, but we\'re on the safe side.
@@ -452,8 +455,12 @@
return '/* evil! */';
}
- // remove html comments
- $source = preg_replace('/(^\s*<\!--)|(-->\s*$)/m', '', $source);
+ // If after removing comments there are still comments it's most likely a hack
+ // Note: In <=1.6 comments are being removed by xss_entity_decode() above
+ // $source = self::remove_css_comments($source);
+ if (strpos($source, '/*') !== false || strpos($source, '<!--') !== false) {
+ return '/* evil! */';
+ }
$url_callback = static function ($url) use ($allow_remote) {
if (strpos($url, 'data:image') === 0) {
@@ -468,8 +475,14 @@
$replacements = new rcube_string_replacer();
// cut out all contents between { and }
- while (($pos = strpos($source, '{', $last_pos)) && ($pos2 = strpos($source, '}', $pos))) {
- $nested = strpos($source, '{', $pos+1);
+ while (($pos = strpos($source, '{', $last_pos)) && ($pos2 = strpos($source, '}', $pos) ?: (strlen($source) - 1))) {
+ // In case there was no closing brace add one
+ if ($source[$pos2] != '}') {
+ $pos2++;
+ $source .= '}';
+ }
+
+ $nested = strpos($source, '{', $pos + 1);
if ($nested && $nested < $pos2) { // when dealing with nested blocks (e.g. @media), take the inner one
$pos = $nested;
}
@@ -559,7 +572,7 @@
$value .= ' url(' . $url . ')';
}
}
- } elseif (preg_match('/;.*/', $val)) {
+ } elseif (preg_match('/;.+/', $val)) {
// Invalid or evil content, ignore
continue;
} else {
@@ -595,19 +608,8 @@
*/
public static function parse_css_block($style)
{
- $pos = 0;
-
- // first remove comments
- while (($pos = strpos($style, '/*', $pos)) !== false) {
- $end = strpos($style, '*/', $pos+2);
-
- if ($end === false) {
- $style = substr($style, 0, $pos);
- }
- else {
- $style = substr_replace($style, '', $pos, $end - $pos + 2);
- }
- }
+ // Remove comments
+ $style = self::remove_css_comments($style);
// Replace new lines with spaces
$style = preg_replace('/[\r\n]+/', ' ', $style);
@@ -660,6 +662,30 @@
}
/**
+ * Remove CSS comments from styles.
+ *
+ * @param string $style CSS style
+ *
+ * @return string CSS style
+ */
+ public static function remove_css_comments($style)
+ {
+ $pos = 0;
+
+ while (($pos = strpos($style, '/*', $pos)) !== false) {
+ $end = strpos($style, '*/', $pos + 2);
+
+ if ($end === false) {
+ $style = substr($style, 0, $pos);
+ } else {
+ $style = substr_replace($style, '', $pos, $end - $pos + 2);
+ }
+ }
+
+ return $style;
+ }
+
+ /**
* Explode css style value
*
* @param string $style CSS style
diff -Nru roundcube-1.6.12+dfsg/program/lib/Roundcube/rcube_washtml.php roundcube-1.6.13+dfsg/program/lib/Roundcube/rcube_washtml.php
--- roundcube-1.6.12+dfsg/program/lib/Roundcube/rcube_washtml.php 2025-12-14 09:10:51.000000000 +0100
+++ roundcube-1.6.13+dfsg/program/lib/Roundcube/rcube_washtml.php 2026-02-08 10:25:02.000000000 +0100
@@ -482,8 +482,7 @@
|| $attr == 'color-profile' // SVG
|| ($attr == 'poster' && $tag == 'video')
|| ($attr == 'src' && preg_match('/^(img|image|source|input|video|audio)$/i', $tag))
- || ($tag == 'use' && $attr == 'href') // SVG
- || ($tag == 'image' && $attr == 'href'); // SVG
+ || ($attr == 'href' && preg_match('/^(feimage|image|use)$/i', $tag)); // SVG
}
/**
diff -Nru roundcube-1.6.12+dfsg/public_html/plugins/managesieve/Changelog roundcube-1.6.13+dfsg/public_html/plugins/managesieve/Changelog
--- roundcube-1.6.12+dfsg/public_html/plugins/managesieve/Changelog 2025-12-14 09:10:51.000000000 +0100
+++ roundcube-1.6.13+dfsg/public_html/plugins/managesieve/Changelog 2026-02-08 10:25:02.000000000 +0100
@@ -1,3 +1,4 @@
+- Fix handling of string-list format values for date tests in Out of Office (#10075)
- Fix invalid line break characters in multi-line text in Sieve scripts (#9543)
- Fix javascript error when relational or spamtest extension is not enabled (#9139)
- Removed managesieve_usetls option (in favor of the scheme prefix in managesieve_host)
diff -Nru roundcube-1.6.12+dfsg/public_html/plugins/managesieve/lib/Roundcube/rcube_sieve_vacation.php roundcube-1.6.13+dfsg/public_html/plugins/managesieve/lib/Roundcube/rcube_sieve_vacation.php
--- roundcube-1.6.12+dfsg/public_html/plugins/managesieve/lib/Roundcube/rcube_sieve_vacation.php 2025-12-14 09:10:51.000000000 +0100
+++ roundcube-1.6.13+dfsg/public_html/plugins/managesieve/lib/Roundcube/rcube_sieve_vacation.php 2026-02-08 10:25:02.000000000 +0100
@@ -150,6 +150,14 @@
}
}
+ // According to RFC5260, currentdate target can be a string-list,
+ // but here we support only a single value (#10074)
+ foreach ($rule['tests'] as $i => $r) {
+ if ($r['test'] == 'currentdate' && is_array($r['arg'])) {
+ $rule['tests'][$i]['arg'] = array_first($r['arg']);
+ }
+ }
+
$this->vacation = array_merge($rule['actions'][0], [
'idx' => $idx,
'disabled' => $rule['disabled'] || !$active,
diff -Nru roundcube-1.6.12+dfsg/tests/Framework/Utils.php roundcube-1.6.13+dfsg/tests/Framework/Utils.php
--- roundcube-1.6.12+dfsg/tests/Framework/Utils.php 2025-12-14 09:10:51.000000000 +0100
+++ roundcube-1.6.13+dfsg/tests/Framework/Utils.php 2026-02-08 10:25:02.000000000 +0100
@@ -276,6 +276,10 @@
$mod = rcube_utils::mod_css_styles(".test { position\n: fixed; top: 0; }", 'rcmbody');
$this->assertEquals("#rcmbody .test { position: absolute; top: 0; }", $mod, "Replace position:fixed with position:absolute (5)");
+ // missing closing brace
+ $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)');
+
// 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]");
@@ -300,9 +304,15 @@
$mod = rcube_utils::mod_css_styles($style, 'rcmbody', true);
$this->assertSame("#rcmbody { color: red; }", $mod);
- $style = "body { background:url(alert('URL!')); }";
- $mod = rcube_utils::mod_css_styles($style, 'rcmbody', true);
- $this->assertSame("#rcmbody {}", $mod);
+ $style = 'body { background:url(alert('URL!')); }';
+ $mod = \rcube_utils::mod_css_styles($style, 'rcmbody', true);
+ $this->assertSame('#rcmbody {}', $mod);
+
+ // CSS comments and nesting
+ $mod = \rcube_utils::mod_css_styles('/* b { content: "*/* {background-color: silver;}', 'rcmbody', true);
+ $this->assertSame('#rcmbody * { background-color: silver; }', $mod);
+ $mod = \rcube_utils::mod_css_styles('//* test */* {background-color: silver;}', 'rcmbody', true);
+ $this->assertSame('/* evil! */', $mod);
}
/**
diff -Nru roundcube-1.6.12+dfsg/tests/Framework/Washtml.php roundcube-1.6.13+dfsg/tests/Framework/Washtml.php
--- roundcube-1.6.12+dfsg/tests/Framework/Washtml.php 2025-12-14 09:10:51.000000000 +0100
+++ roundcube-1.6.13+dfsg/tests/Framework/Washtml.php 2026-02-08 10:25:02.000000000 +0100
@@ -492,6 +492,14 @@
'<html><svg><animate attributeName="href " values="javascript:alert(\'XSS\')" href="#link" /></animate></svg></html>',
'<svg><!-- animate blocked --></svg>',
],
+ [
+ '<html><svg><defs><filter><feImage href="http://external.site"/></filter></defs></html>',
+ '<svg><defs><filter><feImage x-washed="href"></feImage></filter></defs></svg>',
+ ],
+ [
+ '<html><svg><defs><filter><feImage xlink:href="http://external.site"/></filter></defs></html>',
+ '<svg><defs><filter><feImage x-washed="xlink:href"></feImage></filter></defs></svg>',
+ ],
];
}
-------------- next part --------------
diffstat for roundcube-1.6.5+dfsg roundcube-1.6.5+dfsg
changelog | 9 +
patches/CVE-2025-68460.patch | 64 -------------
patches/CVE-2025-68460/01-08de250fb.patch | 64 +++++++++++++
patches/CVE-2025-68460/02-a7349a4e2.patch | 25 +++++
patches/CVE-2026-25916/01-036e851b6.patch | 48 +++++++++
patches/CVE-2026-25916/02-2b5625f1d.patch | 31 ++++++
patches/CVE-2026-26079/01-1f4c3a5af.patch | 145 ++++++++++++++++++++++++++++++
patches/CVE-2026-26079/02-2b5625f1d.patch | 25 +++++
patches/CVE-2026-26079/03-53d75d5df.patch | 42 ++++++++
patches/series | 8 +
10 files changed, 396 insertions(+), 65 deletions(-)
diff -Nru roundcube-1.6.5+dfsg/debian/changelog roundcube-1.6.5+dfsg/debian/changelog
--- roundcube-1.6.5+dfsg/debian/changelog 2025-12-16 09:10:17.000000000 +0100
+++ roundcube-1.6.5+dfsg/debian/changelog 2026-02-11 12:05:21.000000000 +0100
@@ -1,3 +1,12 @@
+roundcube (1.6.5+dfsg-1+deb12u7) bookworm; urgency=medium
+
+ * Cherry pick upstream security fixes from v1.6.13 (closes: #1127447):
+ + Fix CVE-2026-26079: CSS injection vulnerability.
+ + Fix CVE-2026-25916: Remote image blocking bypass via SVG content.
+ + Cherry-pick improvement change for CVE-2025-68460.
+
+ -- Guilhem Moulin <guilhem at debian.org> Wed, 11 Feb 2026 12:05:21 +0100
+
roundcube (1.6.5+dfsg-1+deb12u6) bookworm-security; urgency=high
* Cherry pick upstream security fixes from v1.6.12 (closes: #1122899):
diff -Nru roundcube-1.6.5+dfsg/debian/patches/CVE-2025-68460/01-08de250fb.patch roundcube-1.6.5+dfsg/debian/patches/CVE-2025-68460/01-08de250fb.patch
--- roundcube-1.6.5+dfsg/debian/patches/CVE-2025-68460/01-08de250fb.patch 1970-01-01 01:00:00.000000000 +0100
+++ roundcube-1.6.5+dfsg/debian/patches/CVE-2025-68460/01-08de250fb.patch 2026-02-11 12:05:21.000000000 +0100
@@ -0,0 +1,64 @@
+From: Aleksander Machniak <alec at alec.pl>
+Date: Sun, 14 Dec 2025 09:02:25 +0100
+Subject: Fix Information Disclosure vulnerability in the HTML style sanitizer
+
+reported by somerandomdev
+
+Origin: https://github.com/roundcube/roundcubemail/commit/08de250fba731b634bed188bbe18d2f6ef3c7571
+Bug: https://roundcube.net/news/2025/12/13/security-updates-1.6.12-and-1.5.12
+Bug-Debian: https://bugs.debian.org/1122899
+Bug-Debian-Security: https://security-tracker.debian.org/tracker/CVE-2025-68460
+---
+ program/lib/Roundcube/rcube_utils.php | 3 +++
+ tests/Framework/Utils.php | 4 ++--
+ tests/Framework/Washtml.php | 7 +++++++
+ 3 files changed, 12 insertions(+), 2 deletions(-)
+
+diff --git a/program/lib/Roundcube/rcube_utils.php b/program/lib/Roundcube/rcube_utils.php
+index b5f8606..1110905 100644
+--- a/program/lib/Roundcube/rcube_utils.php
++++ b/program/lib/Roundcube/rcube_utils.php
+@@ -559,6 +559,9 @@ class rcube_utils
+ $value .= ' url(' . $url . ')';
+ }
+ }
++ } elseif (preg_match('/;.*/', $val)) {
++ // Invalid or evil content, ignore
++ continue;
+ } else {
+ // whitelist ?
+ $value .= ' ' . $val;
+diff --git a/tests/Framework/Utils.php b/tests/Framework/Utils.php
+index 019895b..4b43758 100644
+--- a/tests/Framework/Utils.php
++++ b/tests/Framework/Utils.php
+@@ -291,9 +291,9 @@ class Framework_Utils extends PHPUnit\Framework\TestCase
+ $mod = rcube_utils::mod_css_styles($style, 'rcmbody', true);
+ $this->assertSame("#rcmbody { content: ''; color: red; }", $mod);
+
+- $style = "body { content: '< page: ;/style>< page: ;img src onerror=\"alert(\'hello\');\">'; color: red; }";
++ $style = "body { content: '< page: ;/style>< page: ;img src onerror=\"alert(\\'hello\\');\">'; color: red; }";
+ $mod = rcube_utils::mod_css_styles($style, 'rcmbody', true);
+- $this->assertSame("#rcmbody { content: '< page: ;/style>< page: ;img src onerror=\"alert('hello');\">'; color: red; }", $mod);
++ $this->assertSame("#rcmbody { color: red; }", $mod);
+
+ // Removing page: property
+ $style = "body { page: test; color: red }";
+diff --git a/tests/Framework/Washtml.php b/tests/Framework/Washtml.php
+index ace4716..0b9e1e9 100644
+--- a/tests/Framework/Washtml.php
++++ b/tests/Framework/Washtml.php
+@@ -312,6 +312,13 @@ class Framework_Washtml extends PHPUnit\Framework\TestCase
+ $washed = $washer->wash($html);
+
+ $this->assertTrue(strpos($washed, $exp) !== false, "Style quotes XSS issue (#1490227)");
++
++ $html = '<div style=\'content: "\0026quot;; background: url(//http.cat/418); content:""; width: 100%; height: 100%;\'>test</div>';
++
++ $washer = new \rcube_washtml();
++ $washed = $washer->wash($html);
++
++ $this->assertTrue(strpos($washed, '<div x-washed="style">test</div>') !== false);
+ }
+
+ /**
diff -Nru roundcube-1.6.5+dfsg/debian/patches/CVE-2025-68460/02-a7349a4e2.patch roundcube-1.6.5+dfsg/debian/patches/CVE-2025-68460/02-a7349a4e2.patch
--- roundcube-1.6.5+dfsg/debian/patches/CVE-2025-68460/02-a7349a4e2.patch 1970-01-01 01:00:00.000000000 +0100
+++ roundcube-1.6.5+dfsg/debian/patches/CVE-2025-68460/02-a7349a4e2.patch 2026-02-11 12:05:21.000000000 +0100
@@ -0,0 +1,25 @@
+From: Aleksander Machniak <alec at alec.pl>
+Date: Mon, 15 Dec 2025 11:36:05 +0100
+Subject: Fix the regexp so it will produce less false-positives
+
+Origin: https://github.com/roundcube/roundcubemail/commit/a7349a4e21d27e0a3786139e4c879f236cafe4b1
+Bug: https://roundcube.net/news/2025/12/13/security-updates-1.6.12-and-1.5.12
+Bug-Debian: https://bugs.debian.org/1122899
+Bug-Debian-Security: https://security-tracker.debian.org/tracker/CVE-2025-68460
+---
+ program/lib/Roundcube/rcube_utils.php | 2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+diff --git a/program/lib/Roundcube/rcube_utils.php b/program/lib/Roundcube/rcube_utils.php
+index 1110905..13f1915 100644
+--- a/program/lib/Roundcube/rcube_utils.php
++++ b/program/lib/Roundcube/rcube_utils.php
+@@ -559,7 +559,7 @@ class rcube_utils
+ $value .= ' url(' . $url . ')';
+ }
+ }
+- } elseif (preg_match('/;.*/', $val)) {
++ } elseif (preg_match('/;.+/', $val)) {
+ // Invalid or evil content, ignore
+ continue;
+ } else {
diff -Nru roundcube-1.6.5+dfsg/debian/patches/CVE-2025-68460.patch roundcube-1.6.5+dfsg/debian/patches/CVE-2025-68460.patch
--- roundcube-1.6.5+dfsg/debian/patches/CVE-2025-68460.patch 2025-12-16 09:10:17.000000000 +0100
+++ roundcube-1.6.5+dfsg/debian/patches/CVE-2025-68460.patch 1970-01-01 01:00:00.000000000 +0100
@@ -1,64 +0,0 @@
-From: Aleksander Machniak <alec at alec.pl>
-Date: Sun, 14 Dec 2025 09:02:25 +0100
-Subject: Fix Information Disclosure vulnerability in the HTML style sanitizer
-
-reported by somerandomdev
-
-Origin: https://github.com/roundcube/roundcubemail/commit/08de250fba731b634bed188bbe18d2f6ef3c7571
-Bug: https://roundcube.net/news/2025/12/13/security-updates-1.6.12-and-1.5.12
-Bug-Debian: https://bugs.debian.org/1122899
-Bug-Debian-Security: https://security-tracker.debian.org/tracker/CVE-2025-68460
----
- program/lib/Roundcube/rcube_utils.php | 3 +++
- tests/Framework/Utils.php | 4 ++--
- tests/Framework/Washtml.php | 7 +++++++
- 3 files changed, 12 insertions(+), 2 deletions(-)
-
-diff --git a/program/lib/Roundcube/rcube_utils.php b/program/lib/Roundcube/rcube_utils.php
-index b5f8606..1110905 100644
---- a/program/lib/Roundcube/rcube_utils.php
-+++ b/program/lib/Roundcube/rcube_utils.php
-@@ -559,6 +559,9 @@ class rcube_utils
- $value .= ' url(' . $url . ')';
- }
- }
-+ } elseif (preg_match('/;.*/', $val)) {
-+ // Invalid or evil content, ignore
-+ continue;
- } else {
- // whitelist ?
- $value .= ' ' . $val;
-diff --git a/tests/Framework/Utils.php b/tests/Framework/Utils.php
-index 019895b..4b43758 100644
---- a/tests/Framework/Utils.php
-+++ b/tests/Framework/Utils.php
-@@ -291,9 +291,9 @@ class Framework_Utils extends PHPUnit\Framework\TestCase
- $mod = rcube_utils::mod_css_styles($style, 'rcmbody', true);
- $this->assertSame("#rcmbody { content: ''; color: red; }", $mod);
-
-- $style = "body { content: '< page: ;/style>< page: ;img src onerror=\"alert(\'hello\');\">'; color: red; }";
-+ $style = "body { content: '< page: ;/style>< page: ;img src onerror=\"alert(\\'hello\\');\">'; color: red; }";
- $mod = rcube_utils::mod_css_styles($style, 'rcmbody', true);
-- $this->assertSame("#rcmbody { content: '< page: ;/style>< page: ;img src onerror=\"alert('hello');\">'; color: red; }", $mod);
-+ $this->assertSame("#rcmbody { color: red; }", $mod);
-
- // Removing page: property
- $style = "body { page: test; color: red }";
-diff --git a/tests/Framework/Washtml.php b/tests/Framework/Washtml.php
-index ace4716..0b9e1e9 100644
---- a/tests/Framework/Washtml.php
-+++ b/tests/Framework/Washtml.php
-@@ -312,6 +312,13 @@ class Framework_Washtml extends PHPUnit\Framework\TestCase
- $washed = $washer->wash($html);
-
- $this->assertTrue(strpos($washed, $exp) !== false, "Style quotes XSS issue (#1490227)");
-+
-+ $html = '<div style=\'content: "\0026quot;; background: url(//http.cat/418); content:""; width: 100%; height: 100%;\'>test</div>';
-+
-+ $washer = new \rcube_washtml();
-+ $washed = $washer->wash($html);
-+
-+ $this->assertTrue(strpos($washed, '<div x-washed="style">test</div>') !== false);
- }
-
- /**
diff -Nru roundcube-1.6.5+dfsg/debian/patches/CVE-2026-25916/01-036e851b6.patch roundcube-1.6.5+dfsg/debian/patches/CVE-2026-25916/01-036e851b6.patch
--- roundcube-1.6.5+dfsg/debian/patches/CVE-2026-25916/01-036e851b6.patch 1970-01-01 01:00:00.000000000 +0100
+++ roundcube-1.6.5+dfsg/debian/patches/CVE-2026-25916/01-036e851b6.patch 2026-02-11 12:05:21.000000000 +0100
@@ -0,0 +1,48 @@
+From: Aleksander Machniak <alec at alec.pl>
+Date: Sun, 8 Feb 2026 09:21:34 +0100
+Subject: Fix remote image blocking bypass via SVG content reported by
+ nullcathedral
+
+Origin: https://github.com/roundcube/roundcubemail/commit/036e851b683333205813f70acda2dc047b4891c8
+Bug: https://roundcube.net/news/2026/02/08/security-updates-1.6.13-and-1.5.13
+Bug: https://nullcathedral.com/posts/2026-02-08-roundcube-svg-feimage-remote-image-bypass/
+Bug-Debian-Security: https://security-tracker.debian.org/tracker/CVE-2026-25916
+Bug-Debian: https://bugs.debian.org/1127447
+---
+ program/lib/Roundcube/rcube_washtml.php | 3 +--
+ tests/Framework/Washtml.php | 8 ++++++++
+ 2 files changed, 9 insertions(+), 2 deletions(-)
+
+diff --git a/program/lib/Roundcube/rcube_washtml.php b/program/lib/Roundcube/rcube_washtml.php
+index 85972f0..8721fe7 100644
+--- a/program/lib/Roundcube/rcube_washtml.php
++++ b/program/lib/Roundcube/rcube_washtml.php
+@@ -482,8 +482,7 @@ class rcube_washtml
+ || $attr == 'color-profile' // SVG
+ || ($attr == 'poster' && $tag == 'video')
+ || ($attr == 'src' && preg_match('/^(img|image|source|input|video|audio)$/i', $tag))
+- || ($tag == 'use' && $attr == 'href') // SVG
+- || ($tag == 'image' && $attr == 'href'); // SVG
++ || ($attr == 'href' && preg_match('/^(feimage|image|use)$/i', $tag)); // SVG
+ }
+
+ /**
+diff --git a/tests/Framework/Washtml.php b/tests/Framework/Washtml.php
+index 0b9e1e9..be404af 100644
+--- a/tests/Framework/Washtml.php
++++ b/tests/Framework/Washtml.php
+@@ -492,6 +492,14 @@ class Framework_Washtml extends PHPUnit\Framework\TestCase
+ '<html><svg><animate attributeName="href " values="javascript:alert(\'XSS\')" href="#link" /></animate></svg></html>',
+ '<svg><!-- animate blocked --></svg>',
+ ],
++ [
++ '<html><svg><defs><filter><feImage href="http://external.site"/></filter></defs></html>',
++ '<svg><defs><filter><feimage x-washed="href"></feimage></filter></defs></svg>',
++ ],
++ [
++ '<html><svg><defs><filter><feImage xlink:href="http://external.site"/></filter></defs></html>',
++ '<svg><defs><filter><feimage x-washed="xlink:href"></feimage></filter></defs></svg>',
++ ],
+ ];
+ }
+
diff -Nru roundcube-1.6.5+dfsg/debian/patches/CVE-2026-25916/02-2b5625f1d.patch roundcube-1.6.5+dfsg/debian/patches/CVE-2026-25916/02-2b5625f1d.patch
--- roundcube-1.6.5+dfsg/debian/patches/CVE-2026-25916/02-2b5625f1d.patch 1970-01-01 01:00:00.000000000 +0100
+++ roundcube-1.6.5+dfsg/debian/patches/CVE-2026-25916/02-2b5625f1d.patch 2026-02-11 12:05:21.000000000 +0100
@@ -0,0 +1,31 @@
+From: Aleksander Machniak <alec at alec.pl>
+Date: Sun, 8 Feb 2026 10:13:39 +0100
+Subject: Fix regression
+
+Origin: https://github.com/roundcube/roundcubemail/commit/2b5625f1d2ef7e050fd1ae481b2a52dc35466447#diff-458653d23200a96c6f32ce2835e5d77128018494e800b9ead6d9542b778ff88e
+Bug: https://roundcube.net/news/2026/02/08/security-updates-1.6.13-and-1.5.13
+Bug: https://nullcathedral.com/posts/2026-02-08-roundcube-svg-feimage-remote-image-bypass/
+Bug-Debian-Security: https://security-tracker.debian.org/tracker/CVE-2026-25916
+Bug-Debian: https://bugs.debian.org/1127447
+---
+ tests/Framework/Washtml.php | 4 ++--
+ 1 file changed, 2 insertions(+), 2 deletions(-)
+
+diff --git a/tests/Framework/Washtml.php b/tests/Framework/Washtml.php
+index be404af..ef324f8 100644
+--- a/tests/Framework/Washtml.php
++++ b/tests/Framework/Washtml.php
+@@ -494,11 +494,11 @@ class Framework_Washtml extends PHPUnit\Framework\TestCase
+ ],
+ [
+ '<html><svg><defs><filter><feImage href="http://external.site"/></filter></defs></html>',
+- '<svg><defs><filter><feimage x-washed="href"></feimage></filter></defs></svg>',
++ '<svg><defs><filter><feImage x-washed="href"></feImage></filter></defs></svg>',
+ ],
+ [
+ '<html><svg><defs><filter><feImage xlink:href="http://external.site"/></filter></defs></html>',
+- '<svg><defs><filter><feimage x-washed="xlink:href"></feimage></filter></defs></svg>',
++ '<svg><defs><filter><feImage x-washed="xlink:href"></feImage></filter></defs></svg>',
+ ],
+ ];
+ }
diff -Nru roundcube-1.6.5+dfsg/debian/patches/CVE-2026-26079/01-1f4c3a5af.patch roundcube-1.6.5+dfsg/debian/patches/CVE-2026-26079/01-1f4c3a5af.patch
--- roundcube-1.6.5+dfsg/debian/patches/CVE-2026-26079/01-1f4c3a5af.patch 1970-01-01 01:00:00.000000000 +0100
+++ roundcube-1.6.5+dfsg/debian/patches/CVE-2026-26079/01-1f4c3a5af.patch 2026-02-11 12:05:21.000000000 +0100
@@ -0,0 +1,145 @@
+From: Aleksander Machniak <alec at alec.pl>
+Date: Sun, 8 Feb 2026 09:24:29 +0100
+Subject: Fix CSS injection vulnerability reported by CERT Polska
+
+Origin: https://github.com/roundcube/roundcubemail/commit/1f4c3a5af5033747f9685a8a395dbd8228d19816
+Bug: https://roundcube.net/news/2026/02/08/security-updates-1.6.13-and-1.5.13
+Bug-Debian-Security: https://security-tracker.debian.org/tracker/CVE-2026-26079
+Bug-Debian: https://bugs.debian.org/1127447
+---
+ program/lib/Roundcube/rcube_utils.php | 59 +++++++++++++++++++++++++----------
+ tests/Framework/Utils.php | 16 ++++++++--
+ 2 files changed, 55 insertions(+), 20 deletions(-)
+
+diff --git a/program/lib/Roundcube/rcube_utils.php b/program/lib/Roundcube/rcube_utils.php
+index 13f1915..51f5bb7 100644
+--- a/program/lib/Roundcube/rcube_utils.php
++++ b/program/lib/Roundcube/rcube_utils.php
+@@ -445,6 +445,10 @@ class rcube_utils
+ return '/* invalid! */';
+ }
+
++ // remove html and css comments
++ $source = preg_replace('/(^\s*<\!--)|(-->\s*$)/m', '', $source);
++ $source = self::remove_css_comments($source);
++
+ // To prevent from a double-escaping tricks we consider a script with
+ // any escape sequences (after de-escaping them above) an evil script.
+ // This probably catches many valid scripts, but we\'re on the safe side.
+@@ -452,8 +456,10 @@ class rcube_utils
+ return '/* evil! */';
+ }
+
+- // remove html comments
+- $source = preg_replace('/(^\s*<\!--)|(-->\s*$)/m', '', $source);
++ // If after removing comments there are still comments it's most likely a hack
++ if (strpos('/*', $source) !== false || strpos('<!--', $source) !== false) {
++ return '/* evil! */';
++ }
+
+ $url_callback = static function ($url) use ($allow_remote) {
+ if (strpos($url, 'data:image') === 0) {
+@@ -468,8 +474,14 @@ class rcube_utils
+ $replacements = new rcube_string_replacer();
+
+ // cut out all contents between { and }
+- while (($pos = strpos($source, '{', $last_pos)) && ($pos2 = strpos($source, '}', $pos))) {
+- $nested = strpos($source, '{', $pos+1);
++ while (($pos = strpos($source, '{', $last_pos)) && ($pos2 = strpos($source, '}', $pos) ?: (strlen($source) - 1))) {
++ // In case there was no closing brace add one
++ if ($source[$pos2] != '}') {
++ $pos2++;
++ $source .= '}';
++ }
++
++ $nested = strpos($source, '{', $pos + 1);
+ if ($nested && $nested < $pos2) { // when dealing with nested blocks (e.g. @media), take the inner one
+ $pos = $nested;
+ }
+@@ -595,19 +607,8 @@ class rcube_utils
+ */
+ public static function parse_css_block($style)
+ {
+- $pos = 0;
+-
+- // first remove comments
+- while (($pos = strpos($style, '/*', $pos)) !== false) {
+- $end = strpos($style, '*/', $pos+2);
+-
+- if ($end === false) {
+- $style = substr($style, 0, $pos);
+- }
+- else {
+- $style = substr_replace($style, '', $pos, $end - $pos + 2);
+- }
+- }
++ // Remove comments
++ $style = self::remove_css_comments($style);
+
+ // Replace new lines with spaces
+ $style = preg_replace('/[\r\n]+/', ' ', $style);
+@@ -657,6 +658,30 @@ class rcube_utils
+ return $result;
+ }
+
++ /**
++ * Remove CSS comments from styles.
++ *
++ * @param string $style CSS style
++ *
++ * @return string CSS style
++ */
++ public static function remove_css_comments($style)
++ {
++ $pos = 0;
++
++ while (($pos = strpos($style, '/*', $pos)) !== false) {
++ $end = strpos($style, '*/', $pos + 2);
++
++ if ($end === false) {
++ $style = substr($style, 0, $pos);
++ } else {
++ $style = substr_replace($style, '', $pos, $end - $pos + 2);
++ }
++ }
++
++ return $style;
++ }
++
+ /**
+ * Explode css style value
+ *
+diff --git a/tests/Framework/Utils.php b/tests/Framework/Utils.php
+index 4b43758..c0e9aea 100644
+--- a/tests/Framework/Utils.php
++++ b/tests/Framework/Utils.php
+@@ -276,6 +276,10 @@ class Framework_Utils extends PHPUnit\Framework\TestCase
+ $mod = rcube_utils::mod_css_styles(".test { position\n: fixed; top: 0; }", 'rcmbody');
+ $this->assertEquals("#rcmbody .test { position: absolute; top: 0; }", $mod, "Replace position:fixed with position:absolute (5)");
+
++ // missing closing brace
++ $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)');
++
+ // 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]");
+@@ -300,9 +304,15 @@ class Framework_Utils extends PHPUnit\Framework\TestCase
+ $mod = rcube_utils::mod_css_styles($style, 'rcmbody', true);
+ $this->assertSame("#rcmbody { color: red; }", $mod);
+
+- $style = "body { background:url(alert('URL!')); }";
+- $mod = rcube_utils::mod_css_styles($style, 'rcmbody', true);
+- $this->assertSame("#rcmbody {}", $mod);
++ $style = 'body { background:url(alert('URL!')); }';
++ $mod = \rcube_utils::mod_css_styles($style, 'rcmbody', true);
++ $this->assertSame('#rcmbody {}', $mod);
++
++ // CSS comments and nesting
++ $mod = \rcube_utils::mod_css_styles('/* b { content: "*/* {background-color: silver;}', 'rcmbody', true);
++ $this->assertSame('#rcmbody * { background-color: silver; }', $mod);
++ $mod = \rcube_utils::mod_css_styles('//* test */* {background-color: silver;}', 'rcmbody', true);
++ $this->assertSame('/* evil! */', $mod);
+ }
+
+ /**
diff -Nru roundcube-1.6.5+dfsg/debian/patches/CVE-2026-26079/02-2b5625f1d.patch roundcube-1.6.5+dfsg/debian/patches/CVE-2026-26079/02-2b5625f1d.patch
--- roundcube-1.6.5+dfsg/debian/patches/CVE-2026-26079/02-2b5625f1d.patch 1970-01-01 01:00:00.000000000 +0100
+++ roundcube-1.6.5+dfsg/debian/patches/CVE-2026-26079/02-2b5625f1d.patch 2026-02-11 12:05:21.000000000 +0100
@@ -0,0 +1,25 @@
+From: Aleksander Machniak <alec at alec.pl>
+Date: Sun, 8 Feb 2026 10:13:39 +0100
+Subject: Fix regression
+
+Origin: https://github.com/roundcube/roundcubemail/commit/2b5625f1d2ef7e050fd1ae481b2a52dc35466447#diff-a3f09795bbbad6183803c522e358c5aa6a468c84ab3bcc9c5de60f0ab70fa101
+Bug: https://roundcube.net/news/2026/02/08/security-updates-1.6.13-and-1.5.13
+Bug-Debian-Security: https://security-tracker.debian.org/tracker/CVE-2026-26079
+Bug-Debian: https://bugs.debian.org/1127447
+---
+ program/lib/Roundcube/rcube_utils.php | 2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+diff --git a/program/lib/Roundcube/rcube_utils.php b/program/lib/Roundcube/rcube_utils.php
+index 51f5bb7..a29a87d 100644
+--- a/program/lib/Roundcube/rcube_utils.php
++++ b/program/lib/Roundcube/rcube_utils.php
+@@ -457,7 +457,7 @@ class rcube_utils
+ }
+
+ // If after removing comments there are still comments it's most likely a hack
+- if (strpos('/*', $source) !== false || strpos('<!--', $source) !== false) {
++ if (strpos($source, '/*') !== false || strpos($source, '<!--') !== false) {
+ return '/* evil! */';
+ }
+
diff -Nru roundcube-1.6.5+dfsg/debian/patches/CVE-2026-26079/03-53d75d5df.patch roundcube-1.6.5+dfsg/debian/patches/CVE-2026-26079/03-53d75d5df.patch
--- roundcube-1.6.5+dfsg/debian/patches/CVE-2026-26079/03-53d75d5df.patch 1970-01-01 01:00:00.000000000 +0100
+++ roundcube-1.6.5+dfsg/debian/patches/CVE-2026-26079/03-53d75d5df.patch 2026-02-11 12:05:21.000000000 +0100
@@ -0,0 +1,42 @@
+From: Aleksander Machniak <alec at alec.pl>
+Date: Sun, 8 Feb 2026 10:25:02 +0100
+Subject: Fix regression
+
+Origin: https://github.com/roundcube/roundcubemail/commit/53d75d5dfebef235a344d476b900c20c12d52b01
+Bug: https://roundcube.net/news/2026/02/08/security-updates-1.6.13-and-1.5.13
+Bug-Debian-Security: https://security-tracker.debian.org/tracker/CVE-2026-26079
+Bug-Debian: https://bugs.debian.org/1127447
+---
+ program/lib/Roundcube/rcube_utils.php | 5 +++--
+ 1 file changed, 3 insertions(+), 2 deletions(-)
+
+diff --git a/program/lib/Roundcube/rcube_utils.php b/program/lib/Roundcube/rcube_utils.php
+index a29a87d..d847461 100644
+--- a/program/lib/Roundcube/rcube_utils.php
++++ b/program/lib/Roundcube/rcube_utils.php
+@@ -432,7 +432,7 @@ class rcube_utils
+ */
+ public static function mod_css_styles($source, $container_id, $allow_remote = false, $prefix = '')
+ {
+- $source = self::xss_entity_decode($source);
++ $source = self::xss_entity_decode($source);
+
+ // No @import allowed
+ // TODO: We should just remove it, not invalidate the whole content
+@@ -447,7 +447,6 @@ class rcube_utils
+
+ // remove html and css comments
+ $source = preg_replace('/(^\s*<\!--)|(-->\s*$)/m', '', $source);
+- $source = self::remove_css_comments($source);
+
+ // To prevent from a double-escaping tricks we consider a script with
+ // any escape sequences (after de-escaping them above) an evil script.
+@@ -457,6 +456,8 @@ class rcube_utils
+ }
+
+ // If after removing comments there are still comments it's most likely a hack
++ // Note: In <=1.6 comments are being removed by xss_entity_decode() above
++ // $source = self::remove_css_comments($source);
+ if (strpos($source, '/*') !== false || strpos($source, '<!--') !== false) {
+ return '/* evil! */';
+ }
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 2025-12-16 09:10:17.000000000 +0100
+++ roundcube-1.6.5+dfsg/debian/patches/series 2026-02-11 12:05:21.000000000 +0100
@@ -29,4 +29,10 @@
Fix-regression-where-HTML-messages-were-displayed-unstyle.patch
CVE-2025-49113.patch
CVE-2025-68461.patch
-CVE-2025-68460.patch
+CVE-2025-68460/01-08de250fb.patch
+CVE-2025-68460/02-a7349a4e2.patch
+CVE-2026-25916/01-036e851b6.patch
+CVE-2026-25916/02-2b5625f1d.patch
+CVE-2026-26079/01-1f4c3a5af.patch
+CVE-2026-26079/02-2b5625f1d.patch
+CVE-2026-26079/03-53d75d5df.patch
-------------- next part --------------
A non-text attachment was scrubbed...
Name: signature.asc
Type: application/pgp-signature
Size: 833 bytes
Desc: not available
URL: <http://alioth-lists.debian.net/pipermail/pkg-roundcube-maintainers/attachments/20260211/c6e51f23/attachment-0001.sig>
More information about the Pkg-roundcube-maintainers
mailing list