Changes of Revision 3

roundcubemail.spec Changed
x
 
1
@@ -79,6 +79,7 @@
2
 Patch201:       default-configuration.patch
3
 Patch202:       roundcubemail-1.4-beta86-plugin-enigma-homedir.patch
4
 Patch203:       0001-Enigma-Optional-support-for-passwordless-keys-7265.patch
5
+Patch204:       0001-Fix-cross-site-scripting-XSS-vulnerability-in-settin.patch
6
 
7
 BuildArch:      noarch
8
 BuildRoot:      %{_tmppath}/%{name}-%{version}-%{release}-root%(%{__id_u} -n)
9
@@ -1536,6 +1537,7 @@
10
 %patch202 -p1
11
 %endif
12
 %patch203 -p1
13
+%patch204 -p1
14
 
15
 # Remove the results of patching when there's an incidental offset
16
 find . -type f -name "*.orig" | while read file; do
17
0001-Fix-cross-site-scripting-XSS-vulnerability-in-settin.patch Added
201
 
1
@@ -0,0 +1,239 @@
2
+From bf599fe1cfbb9a6a13681524fd27e85aeb1f549a Mon Sep 17 00:00:00 2001
3
+From: Aleksander Machniak <alec@alec.pl>
4
+Date: Sat, 4 Nov 2023 17:52:00 +0100
5
+Subject: PATCH Fix cross-site scripting (XSS) vulnerability in setting
6
+ Content-Type/Content-Disposition for attachment preview/download
7
+
8
+Thanks to rehme.infosec for reporting the issues.
9
+---
10
+ CHANGELOG                               |  2 +
11
+ program/lib/Roundcube/rcube_charset.php | 12 ++++++
12
+ program/lib/Roundcube/rcube_imap.php    |  5 +++
13
+ program/lib/Roundcube/rcube_output.php  | 53 ++++++++++++++++++-------
14
+ program/steps/mail/viewsource.inc       | 18 +++++----
15
+ tests/Framework/Charset.php             | 30 +++++++++++++-
16
+ 6 files changed, 97 insertions(+), 23 deletions(-)
17
+
18
+diff --git a/CHANGELOG b/CHANGELOG
19
+index cab1c743d..ead3d106c 100644
20
+--- a/CHANGELOG
21
++++ b/CHANGELOG
22
+@@ -1,5 +1,7 @@
23
+ # Changelog Roundcube Webmail
24
+ 
25
++- Fix cross-site scripting (XSS) vulnerability in setting Content-Type/Content-Disposition for attachment preview/download
26
++
27
+ RELEASE 1.4.15
28
+ --------------
29
+ - Fix cross-site scripting (XSS) vulnerability in handling of SVG in HTML messages (#9168)
30
+diff --git a/program/lib/Roundcube/rcube_charset.php b/program/lib/Roundcube/rcube_charset.php
31
+index 88eb6001f..1f69e118d 100644
32
+--- a/program/lib/Roundcube/rcube_charset.php
33
++++ b/program/lib/Roundcube/rcube_charset.php
34
+@@ -182,6 +182,18 @@ class rcube_charset
35
+         throw new ErrorException($errstr, 0, $errno);
36
+     }
37
+ 
38
++    /**
39
++     * Validate character set identifier.
40
++     *
41
++     * @param string $input Character set identifier
42
++     *
43
++     * @return bool True if valid, False if not valid
44
++     */
45
++    public static function is_valid($input)
46
++    {
47
++        return is_string($input) && preg_match('|^a-zA-Z0-9_./:#-{2,32}$|', $input) > 0;
48
++    }
49
++
50
+     /**
51
+      * Parse and validate charset name string.
52
+      * Sometimes charset string is malformed, there are also charset aliases,
53
+diff --git a/program/lib/Roundcube/rcube_imap.php b/program/lib/Roundcube/rcube_imap.php
54
+index 714ba33f3..c1eebe1ba 100644
55
+--- a/program/lib/Roundcube/rcube_imap.php
56
++++ b/program/lib/Roundcube/rcube_imap.php
57
+@@ -2129,6 +2129,11 @@ class rcube_imap extends rcube_storage
58
+             $struct->charset = $mime_headers->charset;
59
+         }
60
+ 
61
++        // Sanitize charset for security
62
++        if ($struct->charset && !rcube_charset::is_valid($struct->charset)) {
63
++            $struct->charset = '';
64
++        }
65
++
66
+         // read content encoding
67
+         if (!empty($part5)) {
68
+             $struct->encoding = strtolower($part5);
69
+diff --git a/program/lib/Roundcube/rcube_output.php b/program/lib/Roundcube/rcube_output.php
70
+index 27acc7075..f24c47fda 100644
71
+--- a/program/lib/Roundcube/rcube_output.php
72
++++ b/program/lib/Roundcube/rcube_output.php
73
+@@ -212,7 +212,7 @@ abstract class rcube_output
74
+     }
75
+ 
76
+     /**
77
+-     * Send headers related to file downloads
78
++     * Send headers related to file downloads.
79
+      *
80
+      * @param string $filename File name
81
+      * @param array  $params   Optional parameters:
82
+@@ -225,31 +225,54 @@ abstract class rcube_output
83
+      */
84
+     public function download_headers($filename, $params = array())
85
+     {
86
++        // For security reasons we validate type, filename and charset params.
87
++        // Some HTTP servers might drop a header that is malformed or very long, this then
88
++        // can lead to web browsers unintentionally executing javascript code in the body.
89
++
90
+         if (empty($params'disposition')) {
91
+             $params'disposition' = 'attachment';
92
+         }
93
+ 
94
+-        if ($params'disposition' == 'inline' && stripos($params'type', 'text') === 0) {
95
+-            $params'type' .= '; charset=' . ($params'type_charset' ?: $this->charset);
96
+-        }
97
+-
98
+-        header("Content-Type: " . ($params'type' ?: "application/octet-stream"));
99
++        $ctype       = 'application/octet-stream';
100
++        $disposition = $params'disposition';
101
+ 
102
+-        if ($params'disposition' == 'attachment' && $this->browser->ie) {
103
+-            header("Content-Type: application/force-download");
104
++        if (!empty($params'type') && is_string($params'type') && strlen($params'type') < 256
105
++            && preg_match('/^a-z0-9!#$&.+^_-+\/a-z0-9!#$&.+^_-+$/i', $params'type')
106
++        ) {
107
++            $ctype = $params'type';
108
+         }
109
+ 
110
+-        $disposition = "Content-Disposition: " . $params'disposition';
111
++        if ($disposition == 'inline' && stripos($ctype, 'text') === 0) {
112
++            $charset = $this->charset;
113
++            if (!empty($params'type_charset') && rcube_charset::is_valid($params'type_charset')) {
114
++                $charset = $params'type_charset';
115
++            }
116
+ 
117
+-        // For non-ascii characters we'll use RFC2231 syntax
118
+-        if (!preg_match('/^a-zA-Z0-9_.:,?;@+ -/', $filename)) {
119
+-            $disposition .= sprintf("; filename=\"%s\"", $filename);
120
++            $ctype .= "; charset={$charset}";
121
+         }
122
+-        else {
123
+-            $disposition .= sprintf("; filename*=%s''%s", $params'charset' ?: $this->charset, rawurlencode($filename));
124
++
125
++        if (is_string($filename) && strlen($filename) > 0 && strlen($filename) <= 1024) {
126
++            // For non-ascii characters we'll use RFC2231 syntax
127
++            if (!preg_match('/^a-zA-Z0-9_.:,?;@+ -/', $filename)) {
128
++                $disposition .= "; filename=\"{$filename}\"";
129
++            }
130
++            else {
131
++                $filename = rawurlencode($filename);
132
++                $charset  = $this->charset;
133
++                if (!empty($params'charset') && rcube_charset::is_valid($params'charset')) {
134
++                    $charset = $params'charset';
135
++                }
136
++
137
++                $disposition .= "; filename*={$charset}''{$filename}";
138
++            }
139
+         }
140
+ 
141
+-        header($disposition);
142
++        header("Content-Disposition: {$disposition}");
143
++        header("Content-Type: {$ctype}");
144
++
145
++        if ($params'disposition' == 'attachment' && $this->browser->ie) {
146
++            header("Content-Type: application/force-download");
147
++        }
148
+ 
149
+         if (isset($params'length')) {
150
+             header("Content-Length: " . $params'length');
151
+diff --git a/program/steps/mail/viewsource.inc b/program/steps/mail/viewsource.inc
152
+index 532ea073b..91b1703e0 100644
153
+--- a/program/steps/mail/viewsource.inc
154
++++ b/program/steps/mail/viewsource.inc
155
+@@ -34,23 +34,27 @@ if ($uid = rcube_utils::get_input_value('_uid', rcube_utils::INPUT_GET)) {
156
+         $headers = $RCMAIL->storage->get_message_headers($uid);
157
+     }
158
+ 
159
+-    $charset = $headers->charset ?: $RCMAIL->config->get('default_charset');
160
++    $charset  = $headers->charset ?: $RCMAIL->config->get('default_charset');
161
++    $filename = '';
162
++    $params   = array(
163
++        'type'         => 'text/plain',
164
++        'type_charset' => $charset,
165
++    );
166
+ 
167
+     if (!empty($_GET'_save')) {
168
+         $subject  = rcube_mime::decode_header($headers->subject, $headers->charset);
169
+         $filename = rcmail_filename_from_subject(mb_substr($subject, 0, 128));
170
+         $filename = ($filename ?: $uid)  . '.eml';
171
+ 
172
+-        $RCMAIL->output->download_headers($filename, array(
173
+-                'length'       => $headers->size,
174
+-                'type'         => 'text/plain',
175
+-                'type_charset' => $charset,
176
+-        ));
177
++        $params'length' = $headers->size;
178
++        $params'disposition' = 'attachment';
179
+     }
180
+     else {
181
+-        header("Content-Type: text/plain; charset={$charset}");
182
++        $params'disposition' = 'inline';
183
+     }
184
+ 
185
++    $RCMAIL->output->download_headers($filename, $params);
186
++
187
+     if (isset($message)) {
188
+         $message->get_part_body($part_id, empty($_GET'_save'), 0, -1);
189
+     }
190
+diff --git a/tests/Framework/Charset.php b/tests/Framework/Charset.php
191
+index f36b7b969..af6c4c783 100644
192
+--- a/tests/Framework/Charset.php
193
++++ b/tests/Framework/Charset.php
194
+@@ -9,7 +9,6 @@
195
+  */
196
+ class Framework_Charset extends PHPUnit_Framework_TestCase
197
+ {
198
+-
199
+     /**
200
+      * Data for test_clean()
201
debian.changelog Changed
7
 
1
@@ -1,4 +1,4 @@
2
-roundcubemail (1.4.15-0~kolab2) unstable; urgency=low
3
+roundcubemail (1.4.15-0~kolab4) unstable; urgency=low
4
 
5
   * Release of 1.4.15
6
 
7
debian.series Changed
6
 
1
@@ -1,3 +1,4 @@
2
 default-configuration.patch -p1
3
 roundcubemail-1.4-beta86-plugin-enigma-homedir.patch -p1
4
 0001-Enigma-Optional-support-for-passwordless-keys-7265.patch -p1
5
+0001-Fix-cross-site-scripting-XSS-vulnerability-in-settin.patch -p1
6
roundcubemail.dsc Changed
10
 
1
@@ -2,7 +2,7 @@
2
 Source: roundcubemail
3
 Binary: roundcubemail
4
 Architecture: all
5
-Version: 1:1.4.15-0~kolab3
6
+Version: 1:1.4.15-0~kolab4
7
 Maintainer: Jeroen van Meeuwen <vanmeeuwen@kolabsys.com>
8
 Uploaders: Jeroen van Meeuwen <vanmeeuwen@kolabsys.com>
9
 Homepage: http://www.roundcube.net/
10