Fix check_request() bypass in places using get_uids() [CVE-2018-9846] (#6238)

pull/6465/head
Aleksander Machniak 7 years ago
parent dc9c9c36a8
commit e3dd5b66d2

@ -5,6 +5,7 @@ CHANGELOG Roundcube Webmail
- Fix PHP 7.2: count(): Parameter must be an array in enchant-based spellchecker (#6234) - Fix PHP 7.2: count(): Parameter must be an array in enchant-based spellchecker (#6234)
- Fix possible IMAP command injection and type juggling vulnerabilities (#6229) - Fix possible IMAP command injection and type juggling vulnerabilities (#6229)
- Enigma: Fix key selection for signing - Enigma: Fix key selection for signing
- Fix check_request() bypass in places using get_uids() [CVE-2018-9846] (#6238)
RELEASE 1.3.5 RELEASE 1.3.5
------------- -------------

@ -127,9 +127,7 @@ class archive extends rcube_plugin
$archive_type = $rcmail->config->get('archive_type', ''); $archive_type = $rcmail->config->get('archive_type', '');
$archive_folder = $rcmail->config->get('archive_mbox'); $archive_folder = $rcmail->config->get('archive_mbox');
$archive_prefix = $archive_folder . $delimiter; $archive_prefix = $archive_folder . $delimiter;
$current_mbox = rcube_utils::get_input_value('_mbox', rcube_utils::INPUT_POST);
$search_request = rcube_utils::get_input_value('_search', rcube_utils::INPUT_GPC); $search_request = rcube_utils::get_input_value('_search', rcube_utils::INPUT_GPC);
$uids = rcube_utils::get_input_value('_uid', rcube_utils::INPUT_POST);
// count messages before changing anything // count messages before changing anything
if ($_POST['_from'] != 'show') { if ($_POST['_from'] != 'show') {
@ -149,7 +147,7 @@ class archive extends rcube_plugin
'destinations' => array(), 'destinations' => array(),
); );
foreach (rcmail::get_uids(null, null, $multifolder) as $mbox => $uids) { foreach (rcmail::get_uids(null, null, $multifolder, rcube_utils::INPUT_POST) as $mbox => $uids) {
if (!$archive_folder || strpos($mbox, $archive_prefix) === 0) { if (!$archive_folder || strpos($mbox, $archive_prefix) === 0) {
$count = count($uids); $count = count($uids);
continue; continue;

@ -189,9 +189,10 @@ class managesieve extends rcube_plugin
*/ */
function managesieve_actions() function managesieve_actions()
{ {
$uids = rcmail::get_uids(null, null, $multifolder, rcube_utils::INPUT_POST);
// handle fetching email headers for the new filter form // handle fetching email headers for the new filter form
if ($uid = rcube_utils::get_input_value('_uid', rcube_utils::INPUT_POST)) { if (!empty($uids)) {
$uids = rcmail::get_uids();
$mailbox = key($uids); $mailbox = key($uids);
$message = new rcube_message($uids[$mailbox][0], $mailbox); $message = new rcube_message($uids[$mailbox][0], $mailbox);
$headers = $this->parse_headers($message->headers); $headers = $this->parse_headers($message->headers);

@ -62,7 +62,7 @@ class markasjunk extends rcube_plugin
$rcmail = rcmail::get_instance(); $rcmail = rcmail::get_instance();
$storage = $rcmail->get_storage(); $storage = $rcmail->get_storage();
foreach (rcmail::get_uids() as $mbox => $uids) { foreach (rcmail::get_uids(null, null, $multifolder, rcube_utils::INPUT_POST) as $mbox => $uids) {
$storage->unset_flag($uids, 'NONJUNK', $mbox); $storage->unset_flag($uids, 'NONJUNK', $mbox);
$storage->set_flag($uids, 'JUNK', $mbox); $storage->set_flag($uids, 'JUNK', $mbox);
} }

@ -175,8 +175,8 @@ class zipdownload extends rcube_plugin
{ {
$rcmail = rcmail::get_instance(); $rcmail = rcmail::get_instance();
if ($rcmail->config->get('zipdownload_selection') && !empty($_POST['_uid'])) { if ($rcmail->config->get('zipdownload_selection')) {
$messageset = rcmail::get_uids(); $messageset = rcmail::get_uids(null, null, $multi, rcube_utils::INPUT_POST);
if (count($messageset)) { if (count($messageset)) {
$this->_download_messages($messageset); $this->_download_messages($messageset);
} }

@ -2393,16 +2393,17 @@ class rcmail extends rcube
* @param string $uids UID value to decode * @param string $uids UID value to decode
* @param string $mbox Default mailbox value (if not encoded in UIDs) * @param string $mbox Default mailbox value (if not encoded in UIDs)
* @param bool $is_multifolder Will be set to True if multi-folder request * @param bool $is_multifolder Will be set to True if multi-folder request
* @param int $mode Request mode. Default: rcube_utils::INPUT_GPC.
* *
* @return array List of message UIDs per folder * @return array List of message UIDs per folder
*/ */
public static function get_uids($uids = null, $mbox = null, &$is_multifolder = false) public static function get_uids($uids = null, $mbox = null, &$is_multifolder = false, $mode = null)
{ {
// message UID (or comma-separated list of IDs) is provided in // message UID (or comma-separated list of IDs) is provided in
// the form of <ID>-<MBOX>[,<ID>-<MBOX>]* // the form of <ID>-<MBOX>[,<ID>-<MBOX>]*
$_uid = $uids ?: rcube_utils::get_input_value('_uid', rcube_utils::INPUT_GPC); $_uid = $uids ?: rcube_utils::get_input_value('_uid', $mode ?: rcube_utils::INPUT_GPC);
$_mbox = $mbox ?: (string) rcube_utils::get_input_value('_mbox', rcube_utils::INPUT_GPC); $_mbox = $mbox ?: (string) rcube_utils::get_input_value('_mbox', $mode ?: rcube_utils::INPUT_GPC);
// already a hash array // already a hash array
if (is_array($_uid) && !isset($_uid[0])) { if (is_array($_uid) && !isset($_uid[0])) {
@ -2421,8 +2422,9 @@ class rcmail extends rcube
} }
} }
else { else {
if (is_string($_uid)) if (is_string($_uid)) {
$_uid = explode(',', $_uid); $_uid = explode(',', $_uid);
}
// create a per-folder UIDs array // create a per-folder UIDs array
foreach ((array)$_uid as $uid) { foreach ((array)$_uid as $uid) {
@ -2437,7 +2439,7 @@ class rcmail extends rcube
if ($uid == '*') { if ($uid == '*') {
$result[$mbox] = $uid; $result[$mbox] = $uid;
} }
else { else if (preg_match('/^[0-9:.]+$/', $uid)) {
$result[$mbox][] = $uid; $result[$mbox][] = $uid;
} }
} }

@ -29,7 +29,7 @@ if (!empty($_POST['_uid']) && strlen($_POST['_target_mbox'])) {
$target = rcube_utils::get_input_value('_target_mbox', rcube_utils::INPUT_POST, true); $target = rcube_utils::get_input_value('_target_mbox', rcube_utils::INPUT_POST, true);
$sources = array(); $sources = array();
foreach (rcmail::get_uids(null, null, $multifolder) as $mbox => $uids) { foreach (rcmail::get_uids(null, null, $multifolder, rcube_utils::INPUT_POST) as $mbox => $uids) {
if ($mbox === $target) { if ($mbox === $target) {
$copied++; $copied++;
} }

@ -65,7 +65,7 @@ if ($_uids && $flag) {
$input = array($mbox => '*'); $input = array($mbox => '*');
} }
else { else {
$input = rcmail::get_uids(); $input = rcmail::get_uids(null, null, $dummy, rcube_utils::INPUT_POST);
} }
foreach ($input as $mbox => $uids) { foreach ($input as $mbox => $uids) {
@ -88,10 +88,11 @@ if ($_uids && $flag) {
} }
if ($flag == 'DELETED' && $read_deleted && !empty($_POST['_ruid'])) { if ($flag == 'DELETED' && $read_deleted && !empty($_POST['_ruid'])) {
$ruids = rcube_utils::get_input_value('_ruid', rcube_utils::INPUT_POST); if ($ruids = rcube_utils::get_input_value('_ruid', rcube_utils::INPUT_POST)) {
foreach (rcmail::get_uids($ruids) as $mbox => $uids) { foreach (rcmail::get_uids($ruids) as $mbox => $uids) {
$read += (int)$RCMAIL->storage->set_flag($uids, 'SEEN', $mbox); $read += (int)$RCMAIL->storage->set_flag($uids, 'SEEN', $mbox);
} }
}
if ($read && !$skip_deleted) { if ($read && !$skip_deleted) {
$OUTPUT->command('flag_deleted_as_read', $ruids); $OUTPUT->command('flag_deleted_as_read', $ruids);

@ -39,7 +39,7 @@ if ($RCMAIL->action == 'move' && !empty($_POST['_uid']) && strlen($_POST['_targe
$target = rcube_utils::get_input_value('_target_mbox', rcube_utils::INPUT_POST, true); $target = rcube_utils::get_input_value('_target_mbox', rcube_utils::INPUT_POST, true);
$success = true; $success = true;
foreach (rcmail::get_uids(null, null, $multifolder) as $mbox => $uids) { foreach (rcmail::get_uids(null, null, $multifolder, rcube_utils::INPUT_POST) as $mbox => $uids) {
if ($mbox === $target) { if ($mbox === $target) {
$count += is_array($uids) ? count($uids) : 1; $count += is_array($uids) ? count($uids) : 1;
} }
@ -73,7 +73,7 @@ if ($RCMAIL->action == 'move' && !empty($_POST['_uid']) && strlen($_POST['_targe
} }
// delete messages // delete messages
else if ($RCMAIL->action == 'delete' && !empty($_POST['_uid'])) { else if ($RCMAIL->action == 'delete' && !empty($_POST['_uid'])) {
foreach (rcmail::get_uids(null, null, $multifolder) as $mbox => $uids) { foreach (rcmail::get_uids(null, null, $multifolder, rcube_utils::INPUT_POST) as $mbox => $uids) {
$del += (int)$RCMAIL->storage->delete_message($uids, $mbox); $del += (int)$RCMAIL->storage->delete_message($uids, $mbox);
$count += is_array($uids) ? count($uids) : 1; $count += is_array($uids) ? count($uids) : 1;
$sources[] = $mbox; $sources[] = $mbox;

Loading…
Cancel
Save