[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