Vulnerability: In MyBB before version 1.8.24, the custom MyCode (BBCode) for the visual editor doesn't escape input properly when rendering HTML, resulting in a DOM-based XSS vulnerability. The weakness can be exploited by pointing a victim to a page where the visual editor is active (e.g. as a post or Private Message) and operates on a maliciously crafted MyCode message. This may occur on pages where message content is pre-filled using a GET/POST parameter, or on reply pages where a previously saved malicious message is quoted. After upgrading MyBB to 1.8.24, make sure to update the version attribute in the `codebuttons` template for non-default themes to serve the latest version of the patched `jscripts/bbcodes_sceditor.js` file.
Vulnerability ID: CVE-2020-15139
CWE: CWE-79
Severity score: 2.9
Project: https://github.com/mybb/mybb
Published: 2020-08-10
File: jscripts/bbcodes_sceditor.js
Commit message: Fix MyCode message formatting XSS in visual editor
Commit author: Tomasz Mlynski

Vulnerable version (before fix):
 $(function ($) { 	$.sceditor.formats.bbcode 		.set('align', { 			html: function (element, attrs, content) { 				return '<div align="' + (attrs.defaultattr || 'left') + '">' + content + '</div>'; 			}, 			isInline: false 		}); $(function ($) { 			if (size < 0) { 				size = 0; 			} 			return '<font data-scefontsize="' + attrs.defaultattr + '" size="' + size + '">' + content + '</font>'; 		} 	});  $(function ($) { 			var author = '', 				$elm = $(element), 				$cite = $elm.children('cite').first(); 			$cite.html($cite.text());  			if ($cite.length === 1 || $elm.data('author')) { 				author = $cite.text() || $elm.data('author'); $(function ($) { 			var data = '';  			if (attrs.pid) 				data += ' data-pid="' + attrs.pid + '"';  			if (attrs.dateline) 				data += ' data-dateline="' + attrs.dateline + '"';  			if (typeof attrs.defaultattr !== "undefined") 				content = '<cite>' + attrs.defaultattr.replace(/ /g, '&nbsp;') + '</cite>' + content;  			return '<blockquote' + data + '>' + content + '</blockquote>'; 		}, $(function ($) { 		html: function (token, attrs, content) { 			if (typeof attrs.defaultattr == 'string' && attrs.defaultattr != '' && attrs.defaultattr != '{defaultattr}') { 				return '<font face="' + 					attrs.defaultattr + 					'">' + content + '</font>'; 			} else { 				return content;

Fixed version (after fix):
 $(function ($) { 	$.sceditor.formats.bbcode 		.set('align', { 			html: function (element, attrs, content) { 				return '<div align="' + ($.sceditor.escapeEntities(attrs.defaultattr) || 'left') + '">' + content + '</div>'; 			}, 			isInline: false 		}); $(function ($) { 			if (size < 0) { 				size = 0; 			} 			return '<font data-scefontsize="' + $.sceditor.escapeEntities(attrs.defaultattr) + '" size="' + size + '">' + content + '</font>'; 		} 	});  $(function ($) { 			var author = '', 				$elm = $(element), 				$cite = $elm.children('cite').first();  			if ($cite.length === 1 || $elm.data('author')) { 				author = $cite.text() || $elm.data('author'); $(function ($) { 			var data = '';  			if (attrs.pid) 				data += ' data-pid="' + $.sceditor.escapeEntities(attrs.pid) + '"';  			if (attrs.dateline) 				data += ' data-dateline="' + $.sceditor.escapeEntities(attrs.dateline) + '"';  			if (typeof attrs.defaultattr !== "undefined") 				content = '<cite>' + $.sceditor.escapeEntities(attrs.defaultattr).replace(/ /g, '&nbsp;') + '</cite>' + content;  			return '<blockquote' + data + '>' + content + '</blockquote>'; 		}, $(function ($) { 		html: function (token, attrs, content) { 			if (typeof attrs.defaultattr == 'string' && attrs.defaultattr != '' && attrs.defaultattr != '{defaultattr}') { 				return '<font face="' + 					$.sceditor.escapeEntities(attrs.defaultattr) + 					'">' + content + '</font>'; 			} else { 				return content;

Patch:
patch: @@ -58,7 +58,7 @@ $(function ($) {
 	$.sceditor.formats.bbcode
 		.set('align', {
 			html: function (element, attrs, content) {
-				return '<div align="' + (attrs.defaultattr || 'left') + '">' + content + '</div>';
+				return '<div align="' + ($.sceditor.escapeEntities(attrs.defaultattr) || 'left') + '">' + content + '</div>';
 			},
 			isInline: false
 		});
@@ -168,7 +168,7 @@ $(function ($) {
 			if (size < 0) {
 				size = 0;
 			}
-			return '<font data-scefontsize="' + attrs.defaultattr + '" size="' + size + '">' + content + '</font>';
+			return '<font data-scefontsize="' + $.sceditor.escapeEntities(attrs.defaultattr) + '" size="' + size + '">' + content + '</font>';
 		}
 	});
 
@@ -218,7 +218,6 @@ $(function ($) {
 			var author = '',
 				$elm = $(element),
 				$cite = $elm.children('cite').first();
-			$cite.html($cite.text());
 
 			if ($cite.length === 1 || $elm.data('author')) {
 				author = $cite.text() || $elm.data('author');
@@ -244,13 +243,13 @@ $(function ($) {
 			var data = '';
 
 			if (attrs.pid)
-				data += ' data-pid="' + attrs.pid + '"';
+				data += ' data-pid="' + $.sceditor.escapeEntities(attrs.pid) + '"';
 
 			if (attrs.dateline)
-				data += ' data-dateline="' + attrs.dateline + '"';
+				data += ' data-dateline="' + $.sceditor.escapeEntities(attrs.dateline) + '"';
 
 			if (typeof attrs.defaultattr !== "undefined")
-				content = '<cite>' + attrs.defaultattr.replace(/ /g, '&nbsp;') + '</cite>' + content;
+				content = '<cite>' + $.sceditor.escapeEntities(attrs.defaultattr).replace(/ /g, '&nbsp;') + '</cite>' + content;
 
 			return '<blockquote' + data + '>' + content + '</blockquote>';
 		},
@@ -280,7 +279,7 @@ $(function ($) {
 		html: function (token, attrs, content) {
 			if (typeof attrs.defaultattr == 'string' && attrs.defaultattr != '' && attrs.defaultattr != '{defaultattr}') {
 				return '<font face="' +
-					attrs.defaultattr +
+					$.sceditor.escapeEntities(attrs.defaultattr) +
 					'">' + content + '</font>';
 			} else {
 				return content;
path: jscripts/bbcodes_sceditor.js