From bd0551b22076b82a6d49e9f7a2b2e0c90a1b2326 Mon Sep 17 00:00:00 2001 From: Aleksander Machniak <alec@alec.pl> Date: Fri, 05 Feb 2016 07:25:27 -0500 Subject: [PATCH] Secure also downloads of addressbook exports, managesieve script exports and Enigma keys exports --- program/js/app.js | 142 ++++++++++++++++++++-------------------------- 1 files changed, 62 insertions(+), 80 deletions(-) diff --git a/program/js/app.js b/program/js/app.js index bb1dd32..45fba7e 100644 --- a/program/js/app.js +++ b/program/js/app.js @@ -352,7 +352,7 @@ if (this.gui_objects.mailboxlist) { this.env.unread_counts = {}; this.gui_objects.folderlist = this.gui_objects.mailboxlist; - this.http_request('getunread'); + this.http_request('getunread', {_page: this.env.current_page}); } // init address book widget @@ -1019,7 +1019,7 @@ break; } - this.goto_url('get', qstring+'&_download=1', false); + this.goto_url('get', qstring+'&_download=1', false, true); break; case 'select-all': @@ -1225,10 +1225,10 @@ 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; @@ -1316,13 +1316,13 @@ 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; @@ -1437,7 +1437,7 @@ 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(); } @@ -1485,6 +1485,12 @@ 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() { @@ -3393,12 +3399,12 @@ mailvelope.getKeyring(keyring).then(function(kr) { ref.mailvelope_keyring = kr; ref.mailvelope_init(action, kr); - }).catch(function(err) { + }, function(err) { // attempt to create a new keyring for this app/user mailvelope.createKeyring(keyring).then(function(kr) { ref.mailvelope_keyring = kr; ref.mailvelope_init(action, kr); - }).catch(function(err) { + }, function(err) { console.error(err); }); }); @@ -3435,8 +3441,6 @@ } else if (action == 'compose') { this.env.compose_commands.push('compose-encrypted'); - // display the toolbar button - $('#' + this.buttons['compose-encrypted'][0].id).show(); var is_html = $('input[name="_is_html"]').val() > 0; @@ -3528,7 +3532,7 @@ ref.remove_from_attachment_list(name); }); } - }).catch(function(err) { + }, function(err) { console.error(err); console.log(options); }); @@ -3651,15 +3655,15 @@ form.submit(); - }).catch(function(err) { + }, function(err) { console.log(err); }); // mailvelope_editor.encrypt() - }).catch(function(err) { + }, function(err) { console.error(err); }); // mailvelope_keyring.validKeyForAddress(senders) - }).catch(function(err) { + }, function(err) { console.error(err); }); // mailvelope_keyring.validKeyForAddress(recipients) @@ -3673,7 +3677,7 @@ $(selector).addClass('mailvelope').children().not('iframe').hide(); ref.hide_message(msgid); setTimeout(function() { $(window).resize(); }, 10); - }).catch(function(err) { + }, function(err) { console.error(err); ref.hide_message(msgid); ref.display_message('Message decryption failed: ' + err.message, 'error') @@ -3729,7 +3733,7 @@ if (missing_keys.length) { ref.display_message(ref.get_label('nopubkeyfor').replace('$email', missing_keys.join(', ')), 'warning'); } - }, function() { + }).fail(function() { console.error('Pubkey lookup failed with', arguments); ref.hide_message(lock); ref.display_message('pubkeysearcherror', 'error'); @@ -3827,7 +3831,7 @@ btn.closest('.key').fadeOut(); ref.display_message(ref.get_label('keyimportsuccess').replace('$key', $key), 'confirmation'); } - }).catch(function(err) { + }, function(err) { console.log(err); }); }); @@ -4316,7 +4320,7 @@ '<textarea name="text" id="ffresponsetext" cols="40" rows="8"></textarea></div>' + '</form>'; - buttons[this.gettext('save')] = function(e) { + buttons[this.get_label('save')] = function(e) { var name = $('#ffresponsename').val(), text = $('#ffresponsetext').val(); @@ -4332,11 +4336,11 @@ $(this).dialog('close'); }; - buttons[this.gettext('cancel')] = function() { + buttons[this.get_label('cancel')] = function() { $(this).dialog('close'); }; - this.show_popup_dialog(html, this.gettext('newresponse'), buttons, {button_classes: ['mainaction']}); + this.show_popup_dialog(html, this.get_label('newresponse'), buttons, {button_classes: ['mainaction']}); $('#ffresponsetext').val(text); $('#ffresponsename').select(); @@ -5572,7 +5576,7 @@ // add link to pop back to parent group if (this.env.address_group_stack.length > 1) { $('<a href="#list">...</a>') - .attr('title', this.gettext('uponelevel')) + .attr('title', this.get_label('uponelevel')) .addClass('poplink') .appendTo(boxtitle) .click(function(e){ return ref.command('popgroup','',this); }); @@ -7896,9 +7900,11 @@ } }; - 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) @@ -7927,8 +7933,11 @@ }; // send a http request to the server - this.http_request = function(action, data, lock) + this.http_request = function(action, data, lock, type) { + if (type != 'POST') + type = 'GET'; + if (typeof data !== 'object') data = rcube_parse_query(data); @@ -7952,60 +7961,26 @@ } } - var url = this.url(action, data); - - // send request - this.log('HTTP GET: ' + url); + var url = this.url(action); // reset keep-alive interval this.start_keepalive(); + // send request return $.ajax({ - type: 'GET', url: url, dataType: 'json', + type: type, url: url, data: data, dataType: 'json', success: function(data) { ref.http_response(data); }, error: function(o, status, err) { ref.http_error(o, status, err, lock, action); } }); }; + // send a http GET request to the server + this.http_get = this.http_request; + // send a http POST request to the server this.http_post = function(action, data, lock) { - if (typeof data !== 'object') - data = rcube_parse_query(data); - - data._remote = 1; - data._unlock = lock ? lock : 0; - - // trigger plugin hook - var result = this.triggerEvent('request'+action, data); - - // abort if one of the handlers returned false - if (result === false) { - if (data._unlock) - this.set_busy(false, null, data._unlock); - return false; - } - else if (result !== undefined) { - data = result; - if (data._action) { - action = data._action; - delete data._action; - } - } - - var url = this.url(action); - - // send request - this.log('HTTP POST: ' + url); - - // reset keep-alive interval - this.start_keepalive(); - - return $.ajax({ - type: 'POST', url: url, data: data, dataType: 'json', - success: function(data){ ref.http_response(data); }, - error: function(o, status, err) { ref.http_error(o, status, err, lock, action); } - }); + return this.http_request(action, data, lock, 'POST'); }; // aborts ajax request @@ -8410,7 +8385,7 @@ // html5 file-drop API this.document_drag_hover = function(e, over) { - e.preventDefault(); + // don't e.preventDefault() here to not block text dragging on the page (#1490619) $(this.gui_objects.filedrop)[(over?'addClass':'removeClass')]('active'); }; @@ -8442,7 +8417,7 @@ if (uri = e.dataTransfer.getData('roundcube-uri')) { var ts = new Date().getTime(), // jQuery way to escape filename (#1490530) - content = $('<span>').text(e.dataTransfer.getData('roundcube-name') || this.gettext('attaching')).html(); + content = $('<span>').text(e.dataTransfer.getData('roundcube-name') || this.get_label('attaching')).html(); args._uri = uri; args._uploadid = ts; @@ -8788,14 +8763,10 @@ if (!this.env.browser_capabilities) this.env.browser_capabilities = {}; - if (this.env.browser_capabilities.pdf === undefined) - this.env.browser_capabilities.pdf = this.pdf_support_check(); - - if (this.env.browser_capabilities.flash === undefined) - this.env.browser_capabilities.flash = this.flash_support_check(); - - if (this.env.browser_capabilities.tif === undefined) - this.tif_support_check(); + $.each(['pdf', 'flash', 'tif'], function() { + if (ref.env.browser_capabilities[this] === undefined) + ref.env.browser_capabilities[this] = ref[this + '_support_check'](); + }); }; // Returns browser capabilities string @@ -8814,11 +8785,14 @@ this.tif_support_check = function() { - var img = new Image(); + window.setTimeout(function() { + var img = new Image(); + img.onload = function() { ref.env.browser_capabilities.tif = 1; }; + img.onerror = function() { ref.env.browser_capabilities.tif = 0; }; + img.src = ref.assets_path('program/resources/blank.tif'); + }, 10); - img.onload = function() { ref.env.browser_capabilities.tif = 1; }; - img.onerror = function() { ref.env.browser_capabilities.tif = 0; }; - img.src = this.assets_path('program/resources/blank.tif'); + return 0; }; this.pdf_support_check = function() @@ -8854,6 +8828,14 @@ return 1; } + window.setTimeout(function() { + $('<object>').css({position: 'absolute', left: '-10000px'}) + .attr({data: ref.assets_path('program/resources/dummy.pdf'), width: 1, height: 1, type: 'application/pdf'}) + .load(function() { ref.env.browser_capabilities.pdf = 1; }) + .error(function() { ref.env.browser_capabilities.pdf = 0; }) + .appendTo($('body')); + }, 10); + return 0; }; -- Gitblit v1.9.1