[Pkg-roundcube-maintainers] CVE-2023-47272/roundcube: {bullseye, bookworm}-security uploads
Guilhem Moulin
guilhem at debian.org
Tue Nov 28 22:27:57 GMT 2023
Dear security team,
I'd like to propose the attach debdiffs to fix CVE-2023-47272/roundcube.
Bullseye and Bookworm have respectively been following upstream's LTS
(1.4) and stable (1.6) branch. Upstream has not released 1.4.16 yet so
I backported the fix from the release-1.4 branch for Bullseye. However
for Bookworm I imported new bugfix/security upstream release 1.6.5 like
for previous security fixes.
Both 1.4.15+dfsg.1-1~deb11u2 and 1.6.5+dfsg-1~deb12u1 have been tested.
(Also upstream's new unit tests are run at build time.)
Cheers,
--
Guilhem.
-------------- next part --------------
diffstat for roundcube-1.4.15+dfsg.1 roundcube-1.4.15+dfsg.1
changelog | 8 +
patches/CVE-2023-47272.patch | 226 +++++++++++++++++++++++++++++++++++++++++++
patches/series | 1
3 files changed, 235 insertions(+)
diff -Nru roundcube-1.4.15+dfsg.1/debian/changelog roundcube-1.4.15+dfsg.1/debian/changelog
--- roundcube-1.4.15+dfsg.1/debian/changelog 2023-10-18 23:40:57.000000000 +0200
+++ roundcube-1.4.15+dfsg.1/debian/changelog 2023-11-28 15:49:21.000000000 +0100
@@ -1,3 +1,11 @@
+roundcube (1.4.15+dfsg.1-1~deb11u2) bullseye-security; urgency=high
+
+ * Fix CVE-2023-47272: Cross-site scripting (XSS) vulnerability in setting
+ Content-Type/Content-Disposition for attachment preview/download.
+ (Closes: #1055421)
+
+ -- Guilhem Moulin <guilhem at debian.org> Tue, 28 Nov 2023 15:49:21 +0100
+
roundcube (1.4.15+dfsg.1-1~deb11u1) bullseye-security; urgency=high
* New security/bugfix upstream release:
diff -Nru roundcube-1.4.15+dfsg.1/debian/patches/CVE-2023-47272.patch roundcube-1.4.15+dfsg.1/debian/patches/CVE-2023-47272.patch
--- roundcube-1.4.15+dfsg.1/debian/patches/CVE-2023-47272.patch 1970-01-01 01:00:00.000000000 +0100
+++ roundcube-1.4.15+dfsg.1/debian/patches/CVE-2023-47272.patch 2023-11-28 15:49:21.000000000 +0100
@@ -0,0 +1,226 @@
+From: Aleksander Machniak <alec at alec.pl>
+Date: Sat, 4 Nov 2023 17:52:00 +0100
+Subject: Fix cross-site scripting (XSS) vulnerability in setting
+ Content-Type/Content-Disposition for attachment preview/download
+
+Thanks to rehme.infosec for reporting the issues.
+
+Origin: https://github.com/roundcube/roundcubemail/commit/bf599fe1cfbb9a6a13681524fd27e85aeb1f549a
+Bug-Debian: https://security-tracker.debian.org/tracker/CVE-2023-47272
+Bug-Debian: https://bugs.debian.org/1055421
+---
+ program/lib/Roundcube/rcube_charset.php | 12 ++++++++
+ program/lib/Roundcube/rcube_imap.php | 5 ++++
+ program/lib/Roundcube/rcube_output.php | 53 +++++++++++++++++++++++----------
+ program/steps/mail/viewsource.inc | 18 ++++++-----
+ tests/Framework/Charset.php | 30 ++++++++++++++++++-
+ 5 files changed, 95 insertions(+), 23 deletions(-)
+
+diff --git a/program/lib/Roundcube/rcube_charset.php b/program/lib/Roundcube/rcube_charset.php
+index 88eb600..1f69e11 100644
+--- a/program/lib/Roundcube/rcube_charset.php
++++ b/program/lib/Roundcube/rcube_charset.php
+@@ -182,6 +182,18 @@ class rcube_charset
+ throw new ErrorException($errstr, 0, $errno);
+ }
+
++ /**
++ * Validate character set identifier.
++ *
++ * @param string $input Character set identifier
++ *
++ * @return bool True if valid, False if not valid
++ */
++ public static function is_valid($input)
++ {
++ return is_string($input) && preg_match('|^[a-zA-Z0-9_./:#-]{2,32}$|', $input) > 0;
++ }
++
+ /**
+ * Parse and validate charset name string.
+ * Sometimes charset string is malformed, there are also charset aliases,
+diff --git a/program/lib/Roundcube/rcube_imap.php b/program/lib/Roundcube/rcube_imap.php
+index 714ba33..c1eebe1 100644
+--- a/program/lib/Roundcube/rcube_imap.php
++++ b/program/lib/Roundcube/rcube_imap.php
+@@ -2129,6 +2129,11 @@ class rcube_imap extends rcube_storage
+ $struct->charset = $mime_headers->charset;
+ }
+
++ // Sanitize charset for security
++ if ($struct->charset && !rcube_charset::is_valid($struct->charset)) {
++ $struct->charset = '';
++ }
++
+ // read content encoding
+ if (!empty($part[5])) {
+ $struct->encoding = strtolower($part[5]);
+diff --git a/program/lib/Roundcube/rcube_output.php b/program/lib/Roundcube/rcube_output.php
+index 27acc70..f24c47f 100644
+--- a/program/lib/Roundcube/rcube_output.php
++++ b/program/lib/Roundcube/rcube_output.php
+@@ -212,7 +212,7 @@ abstract class rcube_output
+ }
+
+ /**
+- * Send headers related to file downloads
++ * Send headers related to file downloads.
+ *
+ * @param string $filename File name
+ * @param array $params Optional parameters:
+@@ -225,31 +225,54 @@ abstract class rcube_output
+ */
+ public function download_headers($filename, $params = array())
+ {
++ // For security reasons we validate type, filename and charset params.
++ // Some HTTP servers might drop a header that is malformed or very long, this then
++ // can lead to web browsers unintentionally executing javascript code in the body.
++
+ if (empty($params['disposition'])) {
+ $params['disposition'] = 'attachment';
+ }
+
+- if ($params['disposition'] == 'inline' && stripos($params['type'], 'text') === 0) {
+- $params['type'] .= '; charset=' . ($params['type_charset'] ?: $this->charset);
+- }
+-
+- header("Content-Type: " . ($params['type'] ?: "application/octet-stream"));
++ $ctype = 'application/octet-stream';
++ $disposition = $params['disposition'];
+
+- if ($params['disposition'] == 'attachment' && $this->browser->ie) {
+- header("Content-Type: application/force-download");
++ if (!empty($params['type']) && is_string($params['type']) && strlen($params['type']) < 256
++ && preg_match('/^[a-z0-9!#$&.+^_-]+\/[a-z0-9!#$&.+^_-]+$/i', $params['type'])
++ ) {
++ $ctype = $params['type'];
+ }
+
+- $disposition = "Content-Disposition: " . $params['disposition'];
++ if ($disposition == 'inline' && stripos($ctype, 'text') === 0) {
++ $charset = $this->charset;
++ if (!empty($params['type_charset']) && rcube_charset::is_valid($params['type_charset'])) {
++ $charset = $params['type_charset'];
++ }
+
+- // For non-ascii characters we'll use RFC2231 syntax
+- if (!preg_match('/[^a-zA-Z0-9_.:,?;@+ -]/', $filename)) {
+- $disposition .= sprintf("; filename=\"%s\"", $filename);
++ $ctype .= "; charset={$charset}";
+ }
+- else {
+- $disposition .= sprintf("; filename*=%s''%s", $params['charset'] ?: $this->charset, rawurlencode($filename));
++
++ if (is_string($filename) && strlen($filename) > 0 && strlen($filename) <= 1024) {
++ // For non-ascii characters we'll use RFC2231 syntax
++ if (!preg_match('/[^a-zA-Z0-9_.:,?;@+ -]/', $filename)) {
++ $disposition .= "; filename=\"{$filename}\"";
++ }
++ else {
++ $filename = rawurlencode($filename);
++ $charset = $this->charset;
++ if (!empty($params['charset']) && rcube_charset::is_valid($params['charset'])) {
++ $charset = $params['charset'];
++ }
++
++ $disposition .= "; filename*={$charset}''{$filename}";
++ }
+ }
+
+- header($disposition);
++ header("Content-Disposition: {$disposition}");
++ header("Content-Type: {$ctype}");
++
++ if ($params['disposition'] == 'attachment' && $this->browser->ie) {
++ header("Content-Type: application/force-download");
++ }
+
+ if (isset($params['length'])) {
+ header("Content-Length: " . $params['length']);
+diff --git a/program/steps/mail/viewsource.inc b/program/steps/mail/viewsource.inc
+index 532ea07..91b1703 100644
+--- a/program/steps/mail/viewsource.inc
++++ b/program/steps/mail/viewsource.inc
+@@ -34,23 +34,27 @@ if ($uid = rcube_utils::get_input_value('_uid', rcube_utils::INPUT_GET)) {
+ $headers = $RCMAIL->storage->get_message_headers($uid);
+ }
+
+- $charset = $headers->charset ?: $RCMAIL->config->get('default_charset');
++ $charset = $headers->charset ?: $RCMAIL->config->get('default_charset');
++ $filename = '';
++ $params = array(
++ 'type' => 'text/plain',
++ 'type_charset' => $charset,
++ );
+
+ if (!empty($_GET['_save'])) {
+ $subject = rcube_mime::decode_header($headers->subject, $headers->charset);
+ $filename = rcmail_filename_from_subject(mb_substr($subject, 0, 128));
+ $filename = ($filename ?: $uid) . '.eml';
+
+- $RCMAIL->output->download_headers($filename, array(
+- 'length' => $headers->size,
+- 'type' => 'text/plain',
+- 'type_charset' => $charset,
+- ));
++ $params['length'] = $headers->size;
++ $params['disposition'] = 'attachment';
+ }
+ else {
+- header("Content-Type: text/plain; charset={$charset}");
++ $params['disposition'] = 'inline';
+ }
+
++ $RCMAIL->output->download_headers($filename, $params);
++
+ if (isset($message)) {
+ $message->get_part_body($part_id, empty($_GET['_save']), 0, -1);
+ }
+diff --git a/tests/Framework/Charset.php b/tests/Framework/Charset.php
+index d141aa6..c74f670 100644
+--- a/tests/Framework/Charset.php
++++ b/tests/Framework/Charset.php
+@@ -9,7 +9,6 @@
+ */
+ class Framework_Charset extends \PHPUnit\Framework\TestCase
+ {
+-
+ /**
+ * Data for test_clean()
+ */
+@@ -40,6 +39,35 @@ class Framework_Charset extends \PHPUnit\Framework\TestCase
+ $this->assertDoesNotMatchRegularExpression('/\xD0\xD0/', rcube_charset::clean($bogus));
+ }
+
++ /**
++ * Data for test_is_valid()
++ */
++ function data_is_valid()
++ {
++ $list = [];
++ foreach (mb_list_encodings() as $charset) {
++ $list[] = [$charset, true];
++ }
++
++ return array_merge($list, [
++ ['', false],
++ ['a', false],
++ ['aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa', false],
++ [null, false],
++
++ ['TCVN5712-1:1993', true],
++ ['JUS_I.B1.002', true],
++ ]);
++ }
++
++ /**
++ * @dataProvider data_is_valid
++ */
++ function test_is_valid($input, $result)
++ {
++ $this->assertSame($result, rcube_charset::is_valid($input));
++ }
++
+ /**
+ * Data for test_parse_charset()
+ */
diff -Nru roundcube-1.4.15+dfsg.1/debian/patches/series roundcube-1.4.15+dfsg.1/debian/patches/series
--- roundcube-1.4.15+dfsg.1/debian/patches/series 2023-10-18 23:40:57.000000000 +0200
+++ roundcube-1.4.15+dfsg.1/debian/patches/series 2023-11-28 15:49:21.000000000 +0100
@@ -19,3 +19,4 @@
hint-at-which-packages-needs-installing-under-PHP8.patch
fix-Framework_Washtml-test_wash_xss_tests.patch
bump-upstream-version.patch
+CVE-2023-47272.patch
-------------- next part --------------
diffstat for roundcube-1.6.4+dfsg roundcube-1.6.5+dfsg
CHANGELOG.md | 17 ++-
Makefile | 2
config/defaults.inc.php | 8 -
debian/changelog | 18 +++
debian/patches/default-charset-utf8.patch | 2
debian/patches/use-enchant.patch | 2
plugins/managesieve/lib/Roundcube/rcube_sieve_engine.php | 15 ++
plugins/managesieve/localization/ja_JP.inc | 4
program/actions/mail/viewsource.php | 18 ++-
program/actions/utils/error.php | 1
program/lib/Roundcube/rcube_charset.php | 12 ++
program/lib/Roundcube/rcube_imap.php | 13 +-
program/lib/Roundcube/rcube_imap_generic.php | 12 ++
program/lib/Roundcube/rcube_message.php | 10 +
program/lib/Roundcube/rcube_message_part.php | 7 +
program/lib/Roundcube/rcube_output.php | 54 ++++++----
program/lib/Roundcube/rcube_smtp.php | 7 -
public_html/plugins/managesieve/lib/Roundcube/rcube_sieve_engine.php | 15 ++
public_html/plugins/managesieve/localization/ja_JP.inc | 4
tests/Framework/Charset.php | 30 +++++
20 files changed, 191 insertions(+), 60 deletions(-)
diff -Nru roundcube-1.6.4+dfsg/CHANGELOG.md roundcube-1.6.5+dfsg/CHANGELOG.md
--- roundcube-1.6.4+dfsg/CHANGELOG.md 2023-10-14 18:17:17.000000000 +0200
+++ roundcube-1.6.5+dfsg/CHANGELOG.md 2023-11-04 17:52:34.000000000 +0100
@@ -2,10 +2,21 @@
## Unreleased
+- Fix PHP8 fatal error when parsing a malformed BODYSTRUCTURE (#9171)
+- Fix duplicated Inbox folder on IMAP servers that do not use Inbox folder with all capital letters (#9166)
+- Fix PHP warnings (#9174)
+- Fix UI issue when dealing with an invalid managesieve_default_headers value (#9175)
+- Fix bug where images attached to application/smil messages weren't displayed (#8870)
+- Fix PHP string replacement error in utils/error.php (#9185)
+- Fix regression where `smtp_user` did not allow pre/post strings before/after `%u` placeholder (#9162)
+- Fix cross-site scripting (XSS) vulnerability in setting Content-Type/Content-Disposition for attachment preview/download
+
+## Release 1.6.4
+
- Fix PHP8 warnings (#9142, #9160)
- Fix default 'mime.types' path on Windows (#9113)
- Managesieve: Fix javascript error when relational or spamtest extension is not enabled (#9139)
-- Fix cross-site scripting (XSS) vulnerability in handling of SVG in HTML messages (#9168)
+- Fix cross-site scripting (XSS) vulnerability in handling of SVG in HTML messages [CVE-2023-5631] (#9168)
## Release 1.6.3
@@ -24,7 +35,7 @@
- Fix "Show source" on mobile with x_frame_options = deny (#9084)
- Fix various PHP warnings (#9098)
- Fix deprecated use of ldap_connect() in password's ldap_simple driver (#9060)
-- Fix cross-site scripting (XSS) vulnerability in handling of linkrefs in plain text messages
+- Fix cross-site scripting (XSS) vulnerability in handling of linkrefs in plain text messages [CVE-2023-43770]
## Release 1.6.2
@@ -180,7 +191,7 @@
- Fix locked SQLite database for the CLI tools (#8035)
- Fix Makefile on Linux (#8211)
- Fix so PHP warnings are ignored when resizing a malformed image attachment (#8387)
-- Fix various PHP8 warnings (#8392)
+- Fix various PHP8 warnings (#8392, #9193)
- Fix mail headers injection via the subject field on mail compose (#8404)
- Fix bug where small message/rfc822 parts could not be decoded (#8408)
- Fix setting HTML mode on reply/forward of a signed message (#8405)
diff -Nru roundcube-1.6.4+dfsg/config/defaults.inc.php roundcube-1.6.5+dfsg/config/defaults.inc.php
--- roundcube-1.6.4+dfsg/config/defaults.inc.php 2023-10-14 18:17:17.000000000 +0200
+++ roundcube-1.6.5+dfsg/config/defaults.inc.php 2023-11-04 17:52:34.000000000 +0100
@@ -270,12 +270,12 @@
// of IMAP host (no prefix or port) and SMTP server e.g. ['imap.example.com' => 'smtp.example.net']
$config['smtp_host'] = 'localhost:587';
-// SMTP username (if required) if you use %u as the username Roundcube
-// will use the current username for login
+// SMTP username (if required)
+// Note: %u variable will be replaced with current user's username
$config['smtp_user'] = '%u';
-// SMTP password (if required) if you use %p as the password Roundcube
-// will use the current user's password for login
+// SMTP password (if required)
+// Note: When set to '%p' current user's password will be used
$config['smtp_pass'] = '%p';
// SMTP AUTH type (DIGEST-MD5, CRAM-MD5, LOGIN, PLAIN or empty to use
diff -Nru roundcube-1.6.4+dfsg/debian/changelog roundcube-1.6.5+dfsg/debian/changelog
--- roundcube-1.6.4+dfsg/debian/changelog 2023-10-19 00:20:52.000000000 +0200
+++ roundcube-1.6.5+dfsg/debian/changelog 2023-11-28 16:10:54.000000000 +0100
@@ -1,3 +1,21 @@
+roundcube (1.6.5+dfsg-1~deb12u1) bookworm-security; urgency=high
+
+ * New upstream security and bugfix release:
+ + Fix CVE-2023-47272: Cross-site scripting (XSS) vulnerability in setting
+ Content-Type/Content-Disposition for attachment preview/download.
+ (Closes: #1055421)
+ + Fix PHP8 fatal error when parsing a malformed BODYSTRUCTURE.
+ + Fix UI issue when dealing with an invalid managesieve_default_headers
+ value.
+ + Fix bug where images attached to application/smil messages weren't
+ displayed.
+ + Fix PHP8 warnings.
+ + Fix regression where ‘smtp_user’ did not allow pre/post strings
+ before/after ‘%u’ placeholder.
+ * Refresh d/patches.
+
+ -- Guilhem Moulin <guilhem at debian.org> Tue, 28 Nov 2023 16:10:54 +0100
+
roundcube (1.6.4+dfsg-1~deb12u1) bookworm-security; urgency=high
* New upstream security and bugfix release:
diff -Nru roundcube-1.6.4+dfsg/debian/patches/default-charset-utf8.patch roundcube-1.6.5+dfsg/debian/patches/default-charset-utf8.patch
--- roundcube-1.6.4+dfsg/debian/patches/default-charset-utf8.patch 2023-10-19 00:20:52.000000000 +0200
+++ roundcube-1.6.5+dfsg/debian/patches/default-charset-utf8.patch 2023-11-28 16:10:54.000000000 +0100
@@ -8,7 +8,7 @@
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/config/defaults.inc.php b/config/defaults.inc.php
-index 00f1a8d..4338ec9 100644
+index aa2b1c0..65a8214 100644
--- a/config/defaults.inc.php
+++ b/config/defaults.inc.php
@@ -1259,7 +1259,7 @@ $config['collected_senders'] = true;
diff -Nru roundcube-1.6.4+dfsg/debian/patches/use-enchant.patch roundcube-1.6.5+dfsg/debian/patches/use-enchant.patch
--- roundcube-1.6.4+dfsg/debian/patches/use-enchant.patch 2023-10-19 00:20:52.000000000 +0200
+++ roundcube-1.6.5+dfsg/debian/patches/use-enchant.patch 2023-11-28 16:10:54.000000000 +0100
@@ -10,7 +10,7 @@
1 file changed, 2 insertions(+), 1 deletion(-)
diff --git a/config/defaults.inc.php b/config/defaults.inc.php
-index 85481d2..00f1a8d 100644
+index bfa09da..aa2b1c0 100644
--- a/config/defaults.inc.php
+++ b/config/defaults.inc.php
@@ -939,7 +939,8 @@ $config['spellcheck_dictionary'] = false;
diff -Nru roundcube-1.6.4+dfsg/Makefile roundcube-1.6.5+dfsg/Makefile
--- roundcube-1.6.4+dfsg/Makefile 2023-10-14 18:17:17.000000000 +0200
+++ roundcube-1.6.5+dfsg/Makefile 2023-11-04 17:52:34.000000000 +0100
@@ -69,7 +69,7 @@
(cd roundcubemail-git; find . -name '.gitignore' | xargs rm -f)
(cd roundcubemail-git; find . -name '.travis.yml' | xargs rm -f)
(cd roundcubemail-git; rm -rf tests plugins/*/tests .git* .tx* .ci* .editorconfig* index-test.php Dockerfile Makefile)
- (cd roundcubemail-git; $(SEDI) 's/1.6-git/$(VERSION)/' index.php public_html/index.php program/include/iniset.php program/lib/Roundcube/bootstrap.php)
+ (cd roundcubemail-git; $(SEDI) 's/1.6-git/$(VERSION)/' index.php public_html/index.php installer/index.php program/include/iniset.php program/lib/Roundcube/bootstrap.php)
(cd roundcubemail-git; $(SEDI) 's/# Unreleased/# Release $(VERSION)'/ CHANGELOG.md)
buildtools: /tmp/composer.phar
diff -Nru roundcube-1.6.4+dfsg/plugins/managesieve/lib/Roundcube/rcube_sieve_engine.php roundcube-1.6.5+dfsg/plugins/managesieve/lib/Roundcube/rcube_sieve_engine.php
--- roundcube-1.6.4+dfsg/plugins/managesieve/lib/Roundcube/rcube_sieve_engine.php 2023-10-14 18:17:17.000000000 +0200
+++ roundcube-1.6.5+dfsg/plugins/managesieve/lib/Roundcube/rcube_sieve_engine.php 2023-11-04 17:52:34.000000000 +0100
@@ -727,7 +727,7 @@
$this->form['tests'][$i]['type'] = $sizeop;
$this->form['tests'][$i]['arg'] = $sizetarget;
- if ($sizetarget == '') {
+ if ($sizetarget === '') {
$this->errors['tests'][$i]['sizetarget'] = $this->plugin->gettext('cannotbeempty');
}
else if (!preg_match('/^[0-9]+(K|M|G)?$/i', $sizetarget.$sizeitem, $m)) {
@@ -1067,8 +1067,8 @@
case 'redirect':
case 'redirect_copy':
- $target = $this->strip_value(isset($act_targets[$idx]) ? $act_targets[$idx] : null);
- $domain = $this->strip_value(isset($domain_targets[$idx]) ? $domain_targets[$idx] : null);
+ $target = $this->strip_value($act_targets[$idx] ?? null);
+ $domain = $this->strip_value($domain_targets[$idx] ?? null);
// force one of the configured domains
$domains = (array) $this->rc->config->get('managesieve_domains');
@@ -1082,7 +1082,7 @@
$this->form['actions'][$i]['target'] = $target;
- if ($target == '') {
+ if ($target === '') {
$this->errors['actions'][$i]['target'] = $this->plugin->gettext('cannotbeempty');
}
else if (!rcube_utils::check_email($target)) {
@@ -2776,6 +2776,8 @@
return $str;
}
+ $str = (string) $str;
+
if (!$allow_html) {
$str = strip_tags($str);
}
@@ -3275,6 +3277,11 @@
{
$default = ['Subject', 'From', 'To'];
$headers = (array) $this->rc->config->get('managesieve_default_headers', $default);
+
+ if (empty($headers) || $headers === ['']) {
+ $headers = $default;
+ }
+
$keys = array_map('strtolower', $headers);
$headers = array_combine($keys, $headers);
diff -Nru roundcube-1.6.4+dfsg/plugins/managesieve/localization/ja_JP.inc roundcube-1.6.5+dfsg/plugins/managesieve/localization/ja_JP.inc
--- roundcube-1.6.4+dfsg/plugins/managesieve/localization/ja_JP.inc 2023-10-14 18:17:17.000000000 +0200
+++ roundcube-1.6.5+dfsg/plugins/managesieve/localization/ja_JP.inc 2023-11-04 17:52:34.000000000 +0100
@@ -267,8 +267,8 @@
$messages['setcreated'] = 'フィルターセットを作成しました。';
$messages['activateerror'] = '選択したフィルターを有効にできません。サーバーでエラーが発生しました。';
$messages['deactivateerror'] = '選択したフィルターを無効にできません。サーバーでエラーが発生しました。';
-$messages['deactivated'] = 'フィルターを有効にしました。';
-$messages['activated'] = 'フィルターを無効にしました。';
+$messages['deactivated'] = 'フィルターを無効にしました。';
+$messages['activated'] = 'フィルターを有効にしました。';
$messages['moved'] = 'フィルターを移動しました。';
$messages['moveerror'] = '選択したフィルターを移動できません。サーバーでエラーが発生しました。';
$messages['nametoolong'] = '名前が長すぎます。';
diff -Nru roundcube-1.6.4+dfsg/program/actions/mail/viewsource.php roundcube-1.6.5+dfsg/program/actions/mail/viewsource.php
--- roundcube-1.6.4+dfsg/program/actions/mail/viewsource.php 2023-10-14 18:17:17.000000000 +0200
+++ roundcube-1.6.5+dfsg/program/actions/mail/viewsource.php 2023-11-04 17:52:34.000000000 +0100
@@ -45,26 +45,30 @@
$headers = $rcmail->storage->get_message_headers($uid);
}
- $charset = $headers->charset ?: $rcmail->config->get('default_charset', RCUBE_CHARSET);
+ $charset = $headers->charset ?: $rcmail->config->get('default_charset', RCUBE_CHARSET);
+ $filename = '';
+ $params = [
+ 'type' => 'text/plain',
+ 'type_charset' => $charset,
+ ];
if (!empty($_GET['_save'])) {
$subject = rcube_mime::decode_header($headers->subject, $headers->charset);
$filename = self::filename_from_subject(mb_substr($subject, 0, 128));
$filename = ($filename ?: $uid) . '.eml';
- $rcmail->output->download_headers($filename, [
- 'length' => $headers->size,
- 'type' => 'text/plain',
- 'type_charset' => $charset,
- ]);
+ $params['length'] = $headers->size;
+ $params['disposition'] = 'attachment';
}
else {
// Make sure it works in an iframe (#9084)
$rcmail->output->page_headers();
- header("Content-Type: text/plain; charset={$charset}");
+ $params['disposition'] = 'inline';
}
+ $rcmail->output->download_headers($filename, $params);
+
if (isset($part_id) && isset($message)) {
$message->get_part_body($part_id, empty($_GET['_save']), 0, -1);
}
diff -Nru roundcube-1.6.4+dfsg/program/actions/utils/error.php roundcube-1.6.5+dfsg/program/actions/utils/error.php
--- roundcube-1.6.4+dfsg/program/actions/utils/error.php 2023-10-14 18:17:17.000000000 +0200
+++ roundcube-1.6.5+dfsg/program/actions/utils/error.php 2023-11-04 17:52:34.000000000 +0100
@@ -134,7 +134,6 @@
$output = '<!doctype html><html><head>'
. '<title>' . $product . ':: ERROR</title>'
- . '<link rel="stylesheet" type="text/css" href="skins/$skin/common.css" />'
. '</head><body>'
. '<table border="0" cellspacing="0" cellpadding="0" width="100%" height="80%">'
. '<tr><td align="center">' . $page_content . '</td></tr>'
diff -Nru roundcube-1.6.4+dfsg/program/lib/Roundcube/rcube_charset.php roundcube-1.6.5+dfsg/program/lib/Roundcube/rcube_charset.php
--- roundcube-1.6.4+dfsg/program/lib/Roundcube/rcube_charset.php 2023-10-14 18:17:17.000000000 +0200
+++ roundcube-1.6.5+dfsg/program/lib/Roundcube/rcube_charset.php 2023-11-04 17:52:34.000000000 +0100
@@ -179,6 +179,18 @@
];
/**
+ * Validate character set identifier.
+ *
+ * @param string $input Character set identifier
+ *
+ * @return bool True if valid, False if not valid
+ */
+ public static function is_valid($input)
+ {
+ return is_string($input) && preg_match('|^[a-zA-Z0-9_./:#-]{2,32}$|', $input) > 0;
+ }
+
+ /**
* Parse and validate charset name string.
* Sometimes charset string is malformed, there are also charset aliases,
* but we need strict names for charset conversion (specially utf8 class)
diff -Nru roundcube-1.6.4+dfsg/program/lib/Roundcube/rcube_imap_generic.php roundcube-1.6.5+dfsg/program/lib/Roundcube/rcube_imap_generic.php
--- roundcube-1.6.4+dfsg/program/lib/Roundcube/rcube_imap_generic.php 2023-10-14 18:17:17.000000000 +0200
+++ roundcube-1.6.5+dfsg/program/lib/Roundcube/rcube_imap_generic.php 2023-11-04 17:52:34.000000000 +0100
@@ -1650,6 +1650,18 @@
$mailbox = rtrim($mailbox, $delim);
}
+ // Make it easier for the client to deal with INBOX folder
+ // by always returning the word with all capital letters
+ if (strlen($mailbox) == 5
+ && ($mailbox[0] == 'i' || $mailbox[0] == 'I')
+ && ($mailbox[1] == 'n' || $mailbox[1] == 'N')
+ && ($mailbox[2] == 'b' || $mailbox[2] == 'B')
+ && ($mailbox[3] == 'o' || $mailbox[3] == 'O')
+ && ($mailbox[4] == 'x' || $mailbox[4] == 'X')
+ ) {
+ $mailbox = 'INBOX';
+ }
+
// Add to result array
if (!$lstatus) {
$folders[] = $mailbox;
diff -Nru roundcube-1.6.4+dfsg/program/lib/Roundcube/rcube_imap.php roundcube-1.6.5+dfsg/program/lib/Roundcube/rcube_imap.php
--- roundcube-1.6.4+dfsg/program/lib/Roundcube/rcube_imap.php 2023-10-14 18:17:17.000000000 +0200
+++ roundcube-1.6.5+dfsg/program/lib/Roundcube/rcube_imap.php 2023-11-04 17:52:34.000000000 +0100
@@ -2163,8 +2163,13 @@
$struct->charset = $mime_headers->charset;
}
+ // Sanitize charset for security
+ if ($struct->charset && !rcube_charset::is_valid($struct->charset)) {
+ $struct->charset = '';
+ }
+
// read content encoding
- if (!empty($part[5])) {
+ if (!empty($part[5]) && !is_array($part[5])) {
$struct->encoding = strtolower($part[5]);
$struct->headers['content-transfer-encoding'] = $struct->encoding;
}
@@ -2234,6 +2239,7 @@
if (!empty($part[3])) {
$struct->content_id = $struct->headers['content-id'] = trim($part[3]);
+ // FIXME: This is not the best idea. We should get rid of this at some point
if (empty($struct->disposition)) {
$struct->disposition = 'inline';
}
@@ -2862,11 +2868,6 @@
return false;
}
- if (!$this->conn->data['READ-WRITE']) {
- $this->conn->setError(rcube_imap_generic::ERROR_READONLY, "Folder is read-only");
- return false;
- }
-
// CLOSE(+SELECT) should be faster than EXPUNGE
if (empty($uids) || !empty($all_mode)) {
$result = $this->conn->close();
diff -Nru roundcube-1.6.4+dfsg/program/lib/Roundcube/rcube_message_part.php roundcube-1.6.5+dfsg/program/lib/Roundcube/rcube_message_part.php
--- roundcube-1.6.4+dfsg/program/lib/Roundcube/rcube_message_part.php 2023-10-14 18:17:17.000000000 +0200
+++ roundcube-1.6.5+dfsg/program/lib/Roundcube/rcube_message_part.php 2023-11-04 17:52:34.000000000 +0100
@@ -56,6 +56,13 @@
public $mimetype = 'text/plain';
/**
+ * Real content type (for fake parts)
+ *
+ * @var string|null
+ */
+ public $realtype;
+
+ /**
* Real content type of a message/rfc822 part
*
* @var string
diff -Nru roundcube-1.6.4+dfsg/program/lib/Roundcube/rcube_message.php roundcube-1.6.5+dfsg/program/lib/Roundcube/rcube_message.php
--- roundcube-1.6.4+dfsg/program/lib/Roundcube/rcube_message.php 2023-10-14 18:17:17.000000000 +0200
+++ roundcube-1.6.5+dfsg/program/lib/Roundcube/rcube_message.php 2023-11-04 17:52:34.000000000 +0100
@@ -932,6 +932,16 @@
$mail_part->content_location .= $mail_part->headers['content-location'];
}
+ // application/smil message's are known to use inline images that aren't really inline (#8870)
+ // TODO: This code probably does not belong here. I.e. we should not default to
+ // disposition=inline in rcube_imap::structure_part().
+ if ($primary_type === 'image'
+ && !empty($structure->ctype_parameters['type'])
+ && $structure->ctype_parameters['type'] === 'application/smil'
+ ) {
+ $mail_part->disposition = 'attachment';
+ }
+
// part belongs to a related message and is linked
// Note: mixed is not supposed to contain inline images, but we've found such examples (#5905)
if (
diff -Nru roundcube-1.6.4+dfsg/program/lib/Roundcube/rcube_output.php roundcube-1.6.5+dfsg/program/lib/Roundcube/rcube_output.php
--- roundcube-1.6.4+dfsg/program/lib/Roundcube/rcube_output.php 2023-10-14 18:17:17.000000000 +0200
+++ roundcube-1.6.5+dfsg/program/lib/Roundcube/rcube_output.php 2023-11-04 17:52:34.000000000 +0100
@@ -212,7 +212,7 @@
}
/**
- * Send headers related to file downloads
+ * Send headers related to file downloads.
*
* @param string $filename File name
* @param array $params Optional parameters:
@@ -225,34 +225,54 @@
*/
public function download_headers($filename, $params = [])
{
+ // For security reasons we validate type, filename and charset params.
+ // Some HTTP servers might drop a header that is malformed or very long, this then
+ // can lead to web browsers unintentionally executing javascript code in the body.
+
if (empty($params['disposition'])) {
$params['disposition'] = 'attachment';
}
- if ($params['disposition'] == 'inline' && stripos($params['type'], 'text') === 0) {
- $params['type'] .= '; charset=' . ($params['type_charset'] ?: $this->charset);
+ $ctype = 'application/octet-stream';
+ $disposition = $params['disposition'];
+
+ if (!empty($params['type']) && is_string($params['type']) && strlen($params['type']) < 256
+ && preg_match('/^[a-z0-9!#$&.+^_-]+\/[a-z0-9!#$&.+^_-]+$/i', $params['type'])
+ ) {
+ $ctype = $params['type'];
}
- header("Content-Type: " . (!empty($params['type']) ? $params['type'] : "application/octet-stream"));
+ if ($disposition == 'inline' && stripos($ctype, 'text') === 0) {
+ $charset = $this->charset;
+ if (!empty($params['type_charset']) && rcube_charset::is_valid($params['type_charset'])) {
+ $charset = $params['type_charset'];
+ }
- if ($params['disposition'] == 'attachment' && $this->browser->ie) {
- header("Content-Type: application/force-download");
+ $ctype .= "; charset={$charset}";
}
- $disposition = "Content-Disposition: " . $params['disposition'];
+ if (is_string($filename) && strlen($filename) > 0 && strlen($filename) <= 1024) {
+ // For non-ascii characters we'll use RFC2231 syntax
+ if (!preg_match('/[^a-zA-Z0-9_.:,?;@+ -]/', $filename)) {
+ $disposition .= "; filename=\"{$filename}\"";
+ }
+ else {
+ $filename = rawurlencode($filename);
+ $charset = $this->charset;
+ if (!empty($params['charset']) && rcube_charset::is_valid($params['charset'])) {
+ $charset = $params['charset'];
+ }
- // For non-ascii characters we'll use RFC2231 syntax
- if (!preg_match('/[^a-zA-Z0-9_.:,?;@+ -]/', $filename)) {
- $disposition .= sprintf("; filename=\"%s\"", $filename);
- }
- else {
- $disposition .= sprintf("; filename*=%s''%s",
- !empty($params['charset']) ? $params['charset'] : $this->charset,
- rawurlencode($filename)
- );
+ $disposition .= "; filename*={$charset}''{$filename}";
+ }
}
- header($disposition);
+ header("Content-Disposition: {$disposition}");
+ header("Content-Type: {$ctype}");
+
+ if ($params['disposition'] == 'attachment' && $this->browser->ie) {
+ header("Content-Type: application/force-download");
+ }
if (isset($params['length'])) {
header("Content-Length: " . $params['length']);
diff -Nru roundcube-1.6.4+dfsg/program/lib/Roundcube/rcube_smtp.php roundcube-1.6.5+dfsg/program/lib/Roundcube/rcube_smtp.php
--- roundcube-1.6.4+dfsg/program/lib/Roundcube/rcube_smtp.php 2023-10-14 18:17:17.000000000 +0200
+++ roundcube-1.6.5+dfsg/program/lib/Roundcube/rcube_smtp.php 2023-11-04 17:52:34.000000000 +0100
@@ -170,18 +170,13 @@
}
}
- if ($CONFIG['smtp_user'] == '%u') {
- $smtp_user = (string) $rcube->get_user_name();
- } else {
- $smtp_user = $CONFIG['smtp_user'];
- }
-
if ($CONFIG['smtp_pass'] == '%p') {
$smtp_pass = (string) $rcube->get_user_password();
} else {
$smtp_pass = $CONFIG['smtp_pass'];
}
+ $smtp_user = str_replace('%u', (string) $rcube->get_user_name(), $CONFIG['smtp_user']);
$smtp_auth_type = $CONFIG['smtp_auth_type'] ?: null;
$smtp_authz = null;
diff -Nru roundcube-1.6.4+dfsg/public_html/plugins/managesieve/lib/Roundcube/rcube_sieve_engine.php roundcube-1.6.5+dfsg/public_html/plugins/managesieve/lib/Roundcube/rcube_sieve_engine.php
--- roundcube-1.6.4+dfsg/public_html/plugins/managesieve/lib/Roundcube/rcube_sieve_engine.php 2023-10-14 18:17:17.000000000 +0200
+++ roundcube-1.6.5+dfsg/public_html/plugins/managesieve/lib/Roundcube/rcube_sieve_engine.php 2023-11-04 17:52:34.000000000 +0100
@@ -727,7 +727,7 @@
$this->form['tests'][$i]['type'] = $sizeop;
$this->form['tests'][$i]['arg'] = $sizetarget;
- if ($sizetarget == '') {
+ if ($sizetarget === '') {
$this->errors['tests'][$i]['sizetarget'] = $this->plugin->gettext('cannotbeempty');
}
else if (!preg_match('/^[0-9]+(K|M|G)?$/i', $sizetarget.$sizeitem, $m)) {
@@ -1067,8 +1067,8 @@
case 'redirect':
case 'redirect_copy':
- $target = $this->strip_value(isset($act_targets[$idx]) ? $act_targets[$idx] : null);
- $domain = $this->strip_value(isset($domain_targets[$idx]) ? $domain_targets[$idx] : null);
+ $target = $this->strip_value($act_targets[$idx] ?? null);
+ $domain = $this->strip_value($domain_targets[$idx] ?? null);
// force one of the configured domains
$domains = (array) $this->rc->config->get('managesieve_domains');
@@ -1082,7 +1082,7 @@
$this->form['actions'][$i]['target'] = $target;
- if ($target == '') {
+ if ($target === '') {
$this->errors['actions'][$i]['target'] = $this->plugin->gettext('cannotbeempty');
}
else if (!rcube_utils::check_email($target)) {
@@ -2776,6 +2776,8 @@
return $str;
}
+ $str = (string) $str;
+
if (!$allow_html) {
$str = strip_tags($str);
}
@@ -3275,6 +3277,11 @@
{
$default = ['Subject', 'From', 'To'];
$headers = (array) $this->rc->config->get('managesieve_default_headers', $default);
+
+ if (empty($headers) || $headers === ['']) {
+ $headers = $default;
+ }
+
$keys = array_map('strtolower', $headers);
$headers = array_combine($keys, $headers);
diff -Nru roundcube-1.6.4+dfsg/public_html/plugins/managesieve/localization/ja_JP.inc roundcube-1.6.5+dfsg/public_html/plugins/managesieve/localization/ja_JP.inc
--- roundcube-1.6.4+dfsg/public_html/plugins/managesieve/localization/ja_JP.inc 2023-10-14 18:17:17.000000000 +0200
+++ roundcube-1.6.5+dfsg/public_html/plugins/managesieve/localization/ja_JP.inc 2023-11-04 17:52:34.000000000 +0100
@@ -267,8 +267,8 @@
$messages['setcreated'] = 'フィルターセットを作成しました。';
$messages['activateerror'] = '選択したフィルターを有効にできません。サーバーでエラーが発生しました。';
$messages['deactivateerror'] = '選択したフィルターを無効にできません。サーバーでエラーが発生しました。';
-$messages['deactivated'] = 'フィルターを有効にしました。';
-$messages['activated'] = 'フィルターを無効にしました。';
+$messages['deactivated'] = 'フィルターを無効にしました。';
+$messages['activated'] = 'フィルターを有効にしました。';
$messages['moved'] = 'フィルターを移動しました。';
$messages['moveerror'] = '選択したフィルターを移動できません。サーバーでエラーが発生しました。';
$messages['nametoolong'] = '名前が長すぎます。';
diff -Nru roundcube-1.6.4+dfsg/tests/Framework/Charset.php roundcube-1.6.5+dfsg/tests/Framework/Charset.php
--- roundcube-1.6.4+dfsg/tests/Framework/Charset.php 2023-10-14 18:17:17.000000000 +0200
+++ roundcube-1.6.5+dfsg/tests/Framework/Charset.php 2023-11-04 17:52:34.000000000 +0100
@@ -8,7 +8,6 @@
*/
class Framework_Charset extends PHPUnit\Framework\TestCase
{
-
/**
* Data for test_clean()
*/
@@ -34,6 +33,35 @@
}
/**
+ * Data for test_is_valid()
+ */
+ function data_is_valid()
+ {
+ $list = [];
+ foreach (mb_list_encodings() as $charset) {
+ $list[] = [$charset, true];
+ }
+
+ return array_merge($list, [
+ ['', false],
+ ['a', false],
+ ['aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa', false],
+ [null, false],
+
+ ['TCVN5712-1:1993', true],
+ ['JUS_I.B1.002', true],
+ ]);
+ }
+
+ /**
+ * @dataProvider data_is_valid
+ */
+ function test_is_valid($input, $result)
+ {
+ $this->assertSame($result, rcube_charset::is_valid($input));
+ }
+
+ /**
* Data for test_parse_charset()
*/
function data_parse_charset()
-------------- next part --------------
A non-text attachment was scrubbed...
Name: signature.asc
Type: application/pgp-signature
Size: 833 bytes
Desc: not available
URL: <http://alioth-lists.debian.net/pipermail/pkg-roundcube-maintainers/attachments/20231128/69fdff7c/attachment-0001.sig>
More information about the Pkg-roundcube-maintainers
mailing list