Protect download urls against CSRF using unique request tokens (#1490642)
Send X-Frame-Options headers with every HTTP response
Conflicts:
plugins/enigma/enigma.js
plugins/enigma/lib/enigma_ui.php
program/lib/Roundcube/rcube_message.php
| | |
| | | } |
| | | } |
| | | else if ($action == 'setget') { |
| | | $this->rc->request_security_check(rcube_utils::INPUT_GET); |
| | | |
| | | $script_name = rcube_utils::get_input_value('_set', rcube_utils::INPUT_GPC, true); |
| | | $script = $this->sieve->get_script($script_name); |
| | | |
| | |
| | | var id = this.filtersets_list.get_single_selection(), |
| | | script = this.env.filtersets[id]; |
| | | |
| | | location.href = this.env.comm_path+'&_action=plugin.managesieve-action&_act=setget&_set='+urlencode(script); |
| | | this.goto_url('plugin.managesieve-action', {_act: 'setget', _set: script}, false, true); |
| | | }; |
| | | |
| | | // Set activate/deactivate request |
| | |
| | | // default .eml download of single message |
| | | if (mode == 'eml') { |
| | | var uid = rcmail.get_single_uid(); |
| | | rcmail.goto_url('viewsource', rcmail.params_from_uid(uid, {_save: 1})); |
| | | rcmail.goto_url('viewsource', rcmail.params_from_uid(uid, {_save: 1}), false, true); |
| | | return; |
| | | } |
| | | |
| | |
| | | '_action' => 'plugin.zipdownload.attachments', |
| | | '_mbox' => $rcmail->output->env['mailbox'], |
| | | '_uid' => $rcmail->output->env['uid'], |
| | | )); |
| | | ), false, false, true); |
| | | |
| | | $link = html::a(array('href' => $href, 'class' => 'button zipdownload'), |
| | | rcube::Q($this->gettext('downloadall')) |
| | |
| | | public function download_attachments() |
| | | { |
| | | $rcmail = rcmail::get_instance(); |
| | | |
| | | // require CSRF protected request |
| | | $rcmail->request_security_check(rcube_utils::INPUT_GET); |
| | | |
| | | $imap = $rcmail->get_storage(); |
| | | $temp_dir = $rcmail->config->get('temp_dir'); |
| | | $tmpfname = tempnam($temp_dir, 'zipdownload'); |
| | |
| | | // this need to be full url to make redirects work |
| | | $absolute = true; |
| | | } |
| | | else if ($secure && ($token = $this->get_request_token())) |
| | | $url .= $delm . '_token=' . urlencode($token); |
| | | |
| | | if ($absolute || $full) { |
| | | // add base path to this Roundcube installation |
| | |
| | | // write all javascript commands |
| | | $this->add_script($commands, 'head_top'); |
| | | |
| | | // send clickjacking protection headers |
| | | // allow (legal) iframe content to be loaded |
| | | $iframe = $this->framed || $this->env['framed']; |
| | | if (!headers_sent() && ($xframe = $this->app->config->get('x_frame_options', 'sameorigin'))) { |
| | | header('X-Frame-Options: ' . ($iframe && $xframe == 'deny' ? 'sameorigin' : $xframe)); |
| | | if (!headers_sent() && $iframe && $this->app->config->get('x_frame_options', 'sameorigin') === 'deny') { |
| | | header('X-Frame-Options: sameorigin', true); |
| | | } |
| | | |
| | | // call super method |
| | |
| | | break; |
| | | } |
| | | |
| | | this.goto_url('get', qstring+'&_download=1', false); |
| | | this.goto_url('get', qstring+'&_download=1', false, true); |
| | | break; |
| | | |
| | | case 'select-all': |
| | |
| | | |
| | | case 'download': |
| | | if (this.env.action == 'get') { |
| | | location.href = location.href.replace(/_frame=/, '_download='); |
| | | location.href = this.secure_url(location.href.replace(/_frame=/, '_download=')); |
| | | } |
| | | else if (uid = this.get_single_uid()) { |
| | | this.goto_url('viewsource', this.params_from_uid(uid, {_save: 1})); |
| | | this.goto_url('viewsource', this.params_from_uid(uid, {_save: 1}), false, true); |
| | | } |
| | | break; |
| | | |
| | |
| | | |
| | | case 'export': |
| | | if (this.contact_list.rowcount > 0) { |
| | | this.goto_url('export', { _source: this.env.source, _gid: this.env.group, _search: this.env.search_request }); |
| | | this.goto_url('export', { _source: this.env.source, _gid: this.env.group, _search: this.env.search_request }, false, true); |
| | | } |
| | | break; |
| | | |
| | | case 'export-selected': |
| | | if (this.contact_list.rowcount > 0) { |
| | | this.goto_url('export', { _source: this.env.source, _gid: this.env.group, _cid: this.contact_list.get_selection().join(',') }); |
| | | this.goto_url('export', { _source: this.env.source, _gid: this.env.group, _cid: this.contact_list.get_selection().join(',') }, false, true); |
| | | } |
| | | break; |
| | | |
| | |
| | | if (task == 'mail') |
| | | url += '&_mbox=INBOX'; |
| | | else if (task == 'logout' && !this.env.server_error) { |
| | | url += '&_token=' + this.env.request_token; |
| | | url = this.secure_url(url); |
| | | this.clear_compose_data(); |
| | | } |
| | | |
| | |
| | | |
| | | return url + '?' + name + '=' + value; |
| | | }; |
| | | |
| | | // append CSRF protection token to the given url |
| | | this.secure_url = function(url) |
| | | { |
| | | return this.add_url(url, '_token', this.env.request_token); |
| | | }, |
| | | |
| | | this.is_framed = function() |
| | | { |
| | |
| | | } |
| | | }; |
| | | |
| | | this.goto_url = function(action, query, lock) |
| | | this.goto_url = function(action, query, lock, secure) |
| | | { |
| | | this.redirect(this.url(action, query), lock); |
| | | var url = this.url(action, query) |
| | | if (secure) url = this.secure_url(url); |
| | | this.redirect(url, lock); |
| | | }; |
| | | |
| | | this.location_href = function(url, target, frame) |
| | |
| | | $this->opt = array( |
| | | 'safe' => $this->is_safe, |
| | | 'prefer_html' => $this->app->config->get('prefer_html'), |
| | | 'get_url' => $this->app->url(array( |
| | | 'action' => 'get', |
| | | 'mbox' => $this->storage->get_folder(), |
| | | 'uid' => $uid)) |
| | | 'get_url' => $this->app->url(array( |
| | | 'action' => 'get', |
| | | 'mbox' => $this->storage->get_folder(), |
| | | 'uid' => $uid), |
| | | false, false, true) |
| | | ); |
| | | |
| | | if (!empty($this->headers->structure)) { |
| | |
| | | |
| | | // Request browser to disable DNS prefetching (CVE-2010-0464) |
| | | header("X-DNS-Prefetch-Control: off"); |
| | | |
| | | // send CSRF and clickjacking protection headers |
| | | if ($xframe = $this->app->config->get('x_frame_options', 'sameorigin')) { |
| | | header('X-Frame-Options: ' . $xframe); |
| | | } |
| | | } |
| | | |
| | | /** |
| | |
| | | +-----------------------------------------------------------------------+ |
| | | */ |
| | | |
| | | $RCMAIL->request_security_check(rcube_utils::INPUT_GET); |
| | | |
| | | // Use search result |
| | | if (!empty($_REQUEST['_search']) && isset($_SESSION['search'][$_REQUEST['_search']])) { |
| | | $sort_col = $RCMAIL->config->get('addressbook_sort_col', 'name'); |
| | |
| | | exit; |
| | | } |
| | | |
| | | // require CSRF protected url for downloads |
| | | if ($plugin['download']) |
| | | $RCMAIL->request_security_check(rcube_utils::INPUT_GET); |
| | | |
| | | // overwrite modified vars from plugin |
| | | $mimetype = $plugin['mimetype']; |
| | | $extensions = rcube_mime::get_mime_extensions($mimetype); |
| | |
| | | +-----------------------------------------------------------------------+ |
| | | */ |
| | | |
| | | if (!empty($_GET['_save'])) { |
| | | $RCMAIL->request_security_check(rcube_utils::INPUT_GET); |
| | | } |
| | | |
| | | ob_end_clean(); |
| | | |
| | | // similar code as in program/steps/mail/get.inc |