diff --git a/bower.json b/bower.json index 941398df63..d24a658fed 100644 --- a/bower.json +++ b/bower.json @@ -1,7 +1,7 @@ { "name": "converse.js", "description": "Web-based XMPP/Jabber chat client written in javascript", - "version": "1.0.6", + "version": "1.0.7", "license": "MPL-2.0", "devDependencies": { "jasmine": "https://github.com/jcbrand/jasmine.git#1_3_x", diff --git a/dist/converse-mobile.js b/dist/converse-mobile.js index fcc35e8b21..bc15302ddc 100644 --- a/dist/converse-mobile.js +++ b/dist/converse-mobile.js @@ -1,5 +1,5 @@ /** - * @license almond 0.3.2 Copyright jQuery Foundation and other contributors. + * @license almond 0.3.3 Copyright jQuery Foundation and other contributors. * Released under MIT license, http://github.com/requirejs/almond/LICENSE */ //Going sloppy to avoid 'use strict' string cost, but strict practices should @@ -195,32 +195,39 @@ var requirejs, require, define; return [prefix, name]; } + //Creates a parts array for a relName where first part is plugin ID, + //second part is resource ID. Assumes relName has already been normalized. + function makeRelParts(relName) { + return relName ? splitPrefix(relName) : []; + } + /** * Makes a name map, normalizing the name, and using a plugin * for normalization if necessary. Grabs a ref to plugin * too, as an optimization. */ - makeMap = function (name, relName) { + makeMap = function (name, relParts) { var plugin, parts = splitPrefix(name), - prefix = parts[0]; + prefix = parts[0], + relResourceName = relParts[1]; name = parts[1]; if (prefix) { - prefix = normalize(prefix, relName); + prefix = normalize(prefix, relResourceName); plugin = callDep(prefix); } //Normalize according if (prefix) { if (plugin && plugin.normalize) { - name = plugin.normalize(name, makeNormalize(relName)); + name = plugin.normalize(name, makeNormalize(relResourceName)); } else { - name = normalize(name, relName); + name = normalize(name, relResourceName); } } else { - name = normalize(name, relName); + name = normalize(name, relResourceName); parts = splitPrefix(name); prefix = parts[0]; name = parts[1]; @@ -267,13 +274,14 @@ var requirejs, require, define; }; main = function (name, deps, callback, relName) { - var cjsModule, depName, ret, map, i, + var cjsModule, depName, ret, map, i, relParts, args = [], callbackType = typeof callback, usingExports; //Use name if no relName relName = relName || name; + relParts = makeRelParts(relName); //Call the callback to define the module, if necessary. if (callbackType === 'undefined' || callbackType === 'function') { @@ -282,7 +290,7 @@ var requirejs, require, define; //Default to [require, exports, module] if no deps deps = !deps.length && callback.length ? ['require', 'exports', 'module'] : deps; for (i = 0; i < deps.length; i += 1) { - map = makeMap(deps[i], relName); + map = makeMap(deps[i], relParts); depName = map.f; //Fast path CommonJS standard dependencies. @@ -338,7 +346,7 @@ var requirejs, require, define; //deps arg is the module name, and second arg (if passed) //is just the relName. //Normalize module name, if it contains . or .. - return callDep(makeMap(deps, callback).f); + return callDep(makeMap(deps, makeRelParts(callback)).f); } else if (!deps.splice) { //deps is a config object, not an array. config = deps; @@ -24398,7 +24406,7 @@ define('tpl',['text', 'underscore'], function (text, _) { onload(buildMap[moduleName]); } else { - var ext = (config.tpl && config.tpl.extension) || '.html'; + var ext = config.tpl && !_.isUndefined(config.tpl.extension) ? config.tpl.extension : '.html'; var path = (config.tpl && config.tpl.path) || ''; text.load(path + moduleName + ext, parentRequire, function (source) { buildMap[moduleName] = _.template(source); @@ -29905,7 +29913,14 @@ return Backbone.BrowserStorage; } $forwarded = $message.find('forwarded'); if ($forwarded.length) { - $message = $forwarded.children('message'); + var $forwarded_message = $forwarded.children('message'); + if (Strophe.getBareJidFromJid($forwarded_message.attr('from')) !== from_jid) { + // Prevent message forging via carbons + // + // https://xmpp.org/extensions/xep-0280.html#security + return true; + } + $message = $forwarded_message; $delay = $forwarded.children('delay'); from_jid = $message.attr('from'); to_jid = $message.attr('to'); diff --git a/dist/converse-no-dependencies.js b/dist/converse-no-dependencies.js index e7feaab2b9..b2b1a185b0 100644 --- a/dist/converse-no-dependencies.js +++ b/dist/converse-no-dependencies.js @@ -1,5 +1,5 @@ /** - * @license almond 0.3.2 Copyright jQuery Foundation and other contributors. + * @license almond 0.3.3 Copyright jQuery Foundation and other contributors. * Released under MIT license, http://github.com/requirejs/almond/LICENSE */ //Going sloppy to avoid 'use strict' string cost, but strict practices should @@ -195,32 +195,39 @@ var requirejs, require, define; return [prefix, name]; } + //Creates a parts array for a relName where first part is plugin ID, + //second part is resource ID. Assumes relName has already been normalized. + function makeRelParts(relName) { + return relName ? splitPrefix(relName) : []; + } + /** * Makes a name map, normalizing the name, and using a plugin * for normalization if necessary. Grabs a ref to plugin * too, as an optimization. */ - makeMap = function (name, relName) { + makeMap = function (name, relParts) { var plugin, parts = splitPrefix(name), - prefix = parts[0]; + prefix = parts[0], + relResourceName = relParts[1]; name = parts[1]; if (prefix) { - prefix = normalize(prefix, relName); + prefix = normalize(prefix, relResourceName); plugin = callDep(prefix); } //Normalize according if (prefix) { if (plugin && plugin.normalize) { - name = plugin.normalize(name, makeNormalize(relName)); + name = plugin.normalize(name, makeNormalize(relResourceName)); } else { - name = normalize(name, relName); + name = normalize(name, relResourceName); } } else { - name = normalize(name, relName); + name = normalize(name, relResourceName); parts = splitPrefix(name); prefix = parts[0]; name = parts[1]; @@ -267,13 +274,14 @@ var requirejs, require, define; }; main = function (name, deps, callback, relName) { - var cjsModule, depName, ret, map, i, + var cjsModule, depName, ret, map, i, relParts, args = [], callbackType = typeof callback, usingExports; //Use name if no relName relName = relName || name; + relParts = makeRelParts(relName); //Call the callback to define the module, if necessary. if (callbackType === 'undefined' || callbackType === 'function') { @@ -282,7 +290,7 @@ var requirejs, require, define; //Default to [require, exports, module] if no deps deps = !deps.length && callback.length ? ['require', 'exports', 'module'] : deps; for (i = 0; i < deps.length; i += 1) { - map = makeMap(deps[i], relName); + map = makeMap(deps[i], relParts); depName = map.f; //Fast path CommonJS standard dependencies. @@ -338,7 +346,7 @@ var requirejs, require, define; //deps arg is the module name, and second arg (if passed) //is just the relName. //Normalize module name, if it contains . or .. - return callDep(makeMap(deps, callback).f); + return callDep(makeMap(deps, makeRelParts(callback)).f); } else if (!deps.splice) { //deps is a config object, not an array. config = deps; @@ -888,7 +896,7 @@ define('tpl',['text', 'underscore'], function (text, _) { onload(buildMap[moduleName]); } else { - var ext = (config.tpl && config.tpl.extension) || '.html'; + var ext = config.tpl && !_.isUndefined(config.tpl.extension) ? config.tpl.extension : '.html'; var path = (config.tpl && config.tpl.path) || ''; text.load(path + moduleName + ext, parentRequire, function (source) { buildMap[moduleName] = _.template(source); @@ -4162,7 +4170,14 @@ define("polyfill", function(){}); } $forwarded = $message.find('forwarded'); if ($forwarded.length) { - $message = $forwarded.children('message'); + var $forwarded_message = $forwarded.children('message'); + if (Strophe.getBareJidFromJid($forwarded_message.attr('from')) !== from_jid) { + // Prevent message forging via carbons + // + // https://xmpp.org/extensions/xep-0280.html#security + return true; + } + $message = $forwarded_message; $delay = $forwarded.children('delay'); from_jid = $message.attr('from'); to_jid = $message.attr('to'); diff --git a/dist/converse.js b/dist/converse.js index da8487d849..27af9ad5be 100644 --- a/dist/converse.js +++ b/dist/converse.js @@ -1,5 +1,5 @@ /** - * @license almond 0.3.2 Copyright jQuery Foundation and other contributors. + * @license almond 0.3.3 Copyright jQuery Foundation and other contributors. * Released under MIT license, http://github.com/requirejs/almond/LICENSE */ //Going sloppy to avoid 'use strict' string cost, but strict practices should @@ -195,32 +195,39 @@ var requirejs, require, define; return [prefix, name]; } + //Creates a parts array for a relName where first part is plugin ID, + //second part is resource ID. Assumes relName has already been normalized. + function makeRelParts(relName) { + return relName ? splitPrefix(relName) : []; + } + /** * Makes a name map, normalizing the name, and using a plugin * for normalization if necessary. Grabs a ref to plugin * too, as an optimization. */ - makeMap = function (name, relName) { + makeMap = function (name, relParts) { var plugin, parts = splitPrefix(name), - prefix = parts[0]; + prefix = parts[0], + relResourceName = relParts[1]; name = parts[1]; if (prefix) { - prefix = normalize(prefix, relName); + prefix = normalize(prefix, relResourceName); plugin = callDep(prefix); } //Normalize according if (prefix) { if (plugin && plugin.normalize) { - name = plugin.normalize(name, makeNormalize(relName)); + name = plugin.normalize(name, makeNormalize(relResourceName)); } else { - name = normalize(name, relName); + name = normalize(name, relResourceName); } } else { - name = normalize(name, relName); + name = normalize(name, relResourceName); parts = splitPrefix(name); prefix = parts[0]; name = parts[1]; @@ -267,13 +274,14 @@ var requirejs, require, define; }; main = function (name, deps, callback, relName) { - var cjsModule, depName, ret, map, i, + var cjsModule, depName, ret, map, i, relParts, args = [], callbackType = typeof callback, usingExports; //Use name if no relName relName = relName || name; + relParts = makeRelParts(relName); //Call the callback to define the module, if necessary. if (callbackType === 'undefined' || callbackType === 'function') { @@ -282,7 +290,7 @@ var requirejs, require, define; //Default to [require, exports, module] if no deps deps = !deps.length && callback.length ? ['require', 'exports', 'module'] : deps; for (i = 0; i < deps.length; i += 1) { - map = makeMap(deps[i], relName); + map = makeMap(deps[i], relParts); depName = map.f; //Fast path CommonJS standard dependencies. @@ -338,7 +346,7 @@ var requirejs, require, define; //deps arg is the module name, and second arg (if passed) //is just the relName. //Normalize module name, if it contains . or .. - return callDep(makeMap(deps, callback).f); + return callDep(makeMap(deps, makeRelParts(callback)).f); } else if (!deps.splice) { //deps is a config object, not an array. config = deps; @@ -24398,7 +24406,7 @@ define('tpl',['text', 'underscore'], function (text, _) { onload(buildMap[moduleName]); } else { - var ext = (config.tpl && config.tpl.extension) || '.html'; + var ext = config.tpl && !_.isUndefined(config.tpl.extension) ? config.tpl.extension : '.html'; var path = (config.tpl && config.tpl.path) || ''; text.load(path + moduleName + ext, parentRequire, function (source) { buildMap[moduleName] = _.template(source); @@ -29905,7 +29913,14 @@ return Backbone.BrowserStorage; } $forwarded = $message.find('forwarded'); if ($forwarded.length) { - $message = $forwarded.children('message'); + var $forwarded_message = $forwarded.children('message'); + if (Strophe.getBareJidFromJid($forwarded_message.attr('from')) !== from_jid) { + // Prevent message forging via carbons + // + // https://xmpp.org/extensions/xep-0280.html#security + return true; + } + $message = $forwarded_message; $delay = $forwarded.children('delay'); from_jid = $message.attr('from'); to_jid = $message.attr('to'); diff --git a/docs/CHANGES.md b/docs/CHANGES.md index f9cab54372..55b1d3b130 100755 --- a/docs/CHANGES.md +++ b/docs/CHANGES.md @@ -1,6 +1,6 @@ # Changelog -## 1.0.7 (Unreleased) +## 1.0.7 (2017-02-01) - Security fix: Prevent message forging via carbons. (Thanks to ge0rg) [jcbrand] ## 1.0.6 (2016-08-12) diff --git a/docs/source/conf.py b/docs/source/conf.py index c22321afc7..a332c61d10 100644 --- a/docs/source/conf.py +++ b/docs/source/conf.py @@ -48,9 +48,9 @@ # built documents. # # The short X.Y version. -version = '1.0.6' +version = '1.0.7' # The full version, including alpha/beta/rc tags. -release = '1.0.6' +release = '1.0.7' # The language for content autogenerated by Sphinx. Refer to documentation # for a list of supported languages. diff --git a/locale/converse.pot b/locale/converse.pot index b68b98d60e..3dc58d38b5 100644 --- a/locale/converse.pot +++ b/locale/converse.pot @@ -8,7 +8,7 @@ msgid "" msgstr "" "Project-Id-Version: Converse.js 0.10.1\n" "Report-Msgid-Bugs-To: \n" -"POT-Creation-Date: 2016-08-12 20:41+0000\n" +"POT-Creation-Date: 2017-02-01 12:48+0000\n" "PO-Revision-Date: YEAR-MO-DA HO:MI+ZONE\n" "Last-Translator: FULL NAME \n" "Language-Team: LANGUAGE \n" diff --git a/package.json b/package.json index 4b8e2510dc..f45d19bdaf 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "converse.js", - "version": "1.0.6", + "version": "1.0.7", "description": "Browser based XMPP instant messaging client", "main": "main.js", "directories": {