From ba3efefc7bd2879ee7b9a233981eb4d0fb81c903 Mon Sep 17 00:00:00 2001 From: rugk Date: Wed, 13 Feb 2019 11:59:07 +0100 Subject: [PATCH 01/18] Add warning for insecure HTTP --- js/privatebin.js | 65 ++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 65 insertions(+) diff --git a/js/privatebin.js b/js/privatebin.js index cf747335..52ea8f63 100644 --- a/js/privatebin.js +++ b/js/privatebin.js @@ -4436,6 +4436,7 @@ jQuery.PrivateBin = (function($, sjcl, Base64, RawDeflate) { TopNav.init(); UiHelper.init(); Uploader.init(); + InitialCheck.init(); // check whether existing paste needs to be shown try { @@ -4465,6 +4466,70 @@ jQuery.PrivateBin = (function($, sjcl, Base64, RawDeflate) { return me; })(window, document); + + /** + * initial (security) check + * + * @name InitialCheck + * @param {object} window + * @param {object} document + * @class + */ + var InitialCheck = (function (window, document) { + var me = {}; + + /** + * check if the connection is insecure + * + * @private + * @name InitialCheck.isInsecureConnection + * @function + */ + function isInsecureConnection() + { + const url = new URL(document.URL); + + // HTTP is obviously insecure + if (url.protocol !== 'http:') { + return false; + } + + // filter out actually secure connections over HTTP + if ( + url.hostname.endsWith('.onion') || + url.hostname.endsWith('.i2p') + ) { + return false; + } + + // whitelist localhost for development + if ( + url.hostname === 'localhost' || + url.hostname === '127.0.0.1' + ) { + return false; + } + + // totally INSECURE http protocol! + return true; + } + + /** + * init on application start + * + * @name InitialCheck.init + * @function + */ + me.init = function() + { + if (isInsecureConnection()) { + Alert.showError('This instance is using an insecure connection! Please only use this for testing.'); + } + } + + return me; + })(window, document); + return { Helper: Helper, I18n: I18n, From fc914b4b8471287e6f7fb9c6511c8a2036801711 Mon Sep 17 00:00:00 2001 From: El RIDO Date: Mon, 17 Jun 2019 21:09:21 +0200 Subject: [PATCH 02/18] moved bad bot check into InitialCheck, changed old ie notice into generic update warning, when unsupported user agent is detected and made the other IE alert show in all versions as it is now entirely unsupported --- js/privatebin.js | 161 ++++++++++++++++++++++++++++++---------------- tpl/bootstrap.php | 12 ++-- tpl/page.php | 10 +-- 3 files changed, 116 insertions(+), 67 deletions(-) diff --git a/js/privatebin.js b/js/privatebin.js index 174e8daa..cde67922 100644 --- a/js/privatebin.js +++ b/js/privatebin.js @@ -176,18 +176,6 @@ jQuery.PrivateBin = (function($, RawDeflate) { const Helper = (function () { const me = {}; - /** - * blacklist of UserAgents (parts) known to belong to a bot - * - * @private - * @enum {Object} - * @readonly - */ - const BadBotUA = [ - 'Bot', - 'bot' - ]; - /** * cache for script location * @@ -365,25 +353,6 @@ jQuery.PrivateBin = (function($, RawDeflate) { return baseUri; }; - - /** - * checks whether this is a bot we dislike - * - * @name Helper.isBadBot - * @function - * @return {bool} - */ - me.isBadBot = function() { - // check whether a bot user agent part can be found in the current - // user agent - for (let i = 0; i < BadBotUA.length; ++i) { - if (navigator.userAgent.indexOf(BadBotUA) >= 0) { - return true; - } - } - return false; - } - /** * wrap an object into a Paste, used for mocking in the unit tests * @@ -4561,15 +4530,58 @@ jQuery.PrivateBin = (function($, RawDeflate) { * @param {object} document * @class */ - var InitialCheck = (function (window, document) { + var InitialCheck = (function () { var me = {}; + /** + * blacklist of UserAgents (parts) known to belong to a bot + * + * @private + * @enum {Array} + * @readonly + */ + const badBotUA = [ + 'Bot', + 'bot' + ]; + + /** + * blacklist of UserAgent versions known not to work with this application + * + * @private + * @enum {Object} + * @readonly + */ + const oldUA = [ + { + 'regex': /Chrome\/([0-9]+)/, + 'minVersion': 57, + }, + { + 'regex': /Edge\/([0-9]+)/, + 'minVersion': 16, + }, + { + 'regex': /Firefox\/([0-9]+)/, + 'minVersion': 54, + }, + { + 'regex': /Opera\/.*Version\/([0-9]+)/, + 'minVersion': 44, + }, + { + 'regex': /Version\/([0-9]+).*Safari/, + 'minVersion': 11, + } + ]; + /** * check if the connection is insecure * * @private * @name InitialCheck.isInsecureConnection * @function + * @return {bool} */ function isInsecureConnection() { @@ -4601,20 +4613,73 @@ jQuery.PrivateBin = (function($, RawDeflate) { } /** - * init on application start + * checks whether this is a bot we dislike + * + * @private + * @name InitialCheck.isBadBot + * @function + * @return {bool} + */ + function isBadBot() { + // check whether a bot user agent part can be found in the current + // user agent + for (let i = 0; i < badBotUA.length; ++i) { + if (navigator.userAgent.indexOf(badBotUA) >= 0) { + return true; + } + } + return false; + } + + /** + * checks whether this is an unsupported browser + * + * @private + * @name InitialCheck.isOldBrowser + * @function + * @return {bool} + */ + function isOldBrowser() { + for (let i = 0; i < oldUA.length; ++i) { + let result = oldUA[i]['regex'].exec(navigator.userAgent); + if (result && result[1] < oldUA[i]['minVersion']) { + return true; + } + } + return false; + } + + /** + * init on application start, returns an all-clear signal * * @name InitialCheck.init * @function + * @return {bool} */ me.init = function() { + // prevent bots from viewing a paste and potentially deleting data + // when burn-after-reading is set + if (isBadBot()) { + Alert.showError('I love you too, bot…'); + return false; + } + + if (isOldBrowser()) { + $('#oldnotice').toggle(true); + // execution will likely fail, but the user agent may be + // deliberately set to an incorrect value, so let it proceed + } + if (isInsecureConnection()) { Alert.showError('This instance is using an insecure connection! Please only use this for testing.'); } + + return true; } return me; - })(window, document); + })(); /** * (controller) main PrivateBin logic @@ -4663,18 +4728,6 @@ jQuery.PrivateBin = (function($, RawDeflate) { Alert.hideLoading(); }; - /** - * shows how we much we love bots that execute JS ;) - * - * @name Controller.showBadBotMessage - * @function - */ - me.showBadBotMessage = function() - { - TopNav.hideAllButtons(); - Alert.showError('I love you too, bot…'); - } - /** * shows the loaded paste * @@ -4802,6 +4855,10 @@ jQuery.PrivateBin = (function($, RawDeflate) { // initialize other modules/"classes" Alert.init(); + if (!InitialCheck.init()) { + // something major is wrong, stop right away + return; + } Model.init(); AttachmentViewer.init(); DiscussionViewer.init(); @@ -4811,7 +4868,6 @@ jQuery.PrivateBin = (function($, RawDeflate) { Prompt.init(); TopNav.init(); UiHelper.init(); - InitialCheck.init(); z = (await zlib); // check whether existing paste needs to be shown @@ -4822,19 +4878,12 @@ jQuery.PrivateBin = (function($, RawDeflate) { return me.newPaste(); } - // if delete token is passed (i.e. paste has been deleted by this access) - // there is no more stuf we need to do + // if delete token is passed (i.e. paste has been deleted by this + // access), there is nothing more to do if (Model.hasDeleteToken()) { return; } - // prevent bots from viewing a paste and potentially deleting data - // when burn-after-reading is set - // see https://github.com/elrido/ZeroBin/issues/11 - if (Helper.isBadBot()) { - return me.showBadBotMessage(); - } - // display an existing paste return me.showPaste(); } diff --git a/tpl/bootstrap.php b/tpl/bootstrap.php index a53cdc78..c09fbd30 100644 --- a/tpl/bootstrap.php +++ b/tpl/bootstrap.php @@ -72,9 +72,9 @@ if ($MARKDOWN): endif; ?> - - @@ -449,16 +449,16 @@ endif;