CVE-2021-23390: Improper Control of Generation of Code ('Code Injection') (CWE-94)
value: The package total4 before 0.0.43 are vulnerable to Arbitrary Code Execution via the U.set() and U.get() functions.
CWE description: The product constructs all or part of a code segment using externally-influenced input from an upstream component, but it does not neutralize or incorrectly neutralizes special elements that could modify the syntax or behavior of the intended code segment.
CVSS v3 base score: 9.8
Published: 2021-07-12T16:15Z
Repository: https://github.com/totaljs/framework4
Language: JavaScript
Files changed: changelog.txt, utils.js
Commit date: 2021-06-04 11:37:12 +0200
Commit message: Removed useless methods.

Diff: diff --git a/changelog.txt b/changelog.txt
index 5470f57..82614d6 100644
--- a/changelog.txt
+++ b/changelog.txt
@@ -1,10 +1,14 @@
 ========================
 0.0.43
 ========================
 
 - improved `flowinstance.newmessage(data)` method
+- removed method `U.set()`
+- removed method `U.get()`
+- removed method `U.sync()` and `global.sync()`
+- removed method `U.sync2()` and `global.sync2()`
 
 ========================
 0.0.42
 ========================
 
diff --git a/utils.js b/utils.js
index 9e611a4..1f19227 100755
--- a/utils.js
+++ b/utils.js
@@ -5201,68 +5201,10 @@ FLP.next = function() {
 	}
 
 	self.onComplete(self.file, self.directory);
 };
 
-exports.sync = function(fn, owner) {
-	return function() {
-
-		var args = [].slice.call(arguments);
-		var params;
-		var callback;
-		var executed = false;
-		var self = owner || this;
-
-		args.push(function() {
-			params = arguments;
-			if (!executed && callback) {
-				executed = true;
-				callback.apply(self, params);
-			}
-		});
-
-		fn.apply(self, args);
-
-		return function(cb) {
-			callback = cb;
-			if (!executed && params) {
-				executed = true;
-				callback.apply(self, params);
-			}
-		};
-	};
-};
-
-exports.sync2 = function(fn, owner) {
-	return (function() {
-
-		var params;
-		var callback;
-		var executed = false;
-		var self = owner || this;
-		var args = [].slice.call(arguments);
-
-		args.push(function() {
-			params = arguments;
-			if (!executed && callback) {
-				executed = true;
-				callback.apply(self, params);
-			}
-		});
-
-		fn.apply(self, args);
-
-		return function(cb) {
-			callback = cb;
-			if (!executed && params) {
-				executed = true;
-				callback.apply(self, params);
-			}
-		};
-	})();
-};
-
 exports.async = function(fn, isApply) {
 	var context = this;
 	return function(complete) {
 
 		var self = this;
@@ -5473,96 +5415,10 @@ exports.parseTheme = function(value) {
 		return '';
 	value = value.substring(1, index);
 	return value === '?' ? CONF.default_theme : value;
 };
 
-exports.set = function(obj, path, value) {
-	var cachekey = 'S+' + path;
-
-	if (F.temporary.other[cachekey])
-		return F.temporary.other[cachekey](obj, value);
-
-	var arr = parsepath(path);
-	var builder = [];
-
-	for (var i = 0; i < arr.length - 1; i++) {
-		var type = arr[i + 1] ? (REGISARR.test(arr[i + 1]) ? '[]' : '{}') : '{}';
-		var p = 'w' + (arr[i][0] === '[' ? '' : '.') + arr[i];
-		builder.push('if(typeof(' + p + ')!==\'object\'||' + p + '==null)' + p + '=' + type + ';');
-	}
-
-	var v = arr[arr.length - 1];
-	var ispush = v.lastIndexOf('[]') !== -1;
-	var a = builder.join(';') + ';var v=typeof(a)===\'function\'?a(U.get(b)):a;w' + (v[0] === '[' ? '' : '.') + (ispush ? v.replace(REGREPLACEARR, '.push(v)') : (v + '=v')) + ';return v';
-
-	if ((/__proto__|constructor|prototype|eval/).test(a))
-		throw new Error('Potential vulnerability');
-
-	var fn = new Function('w', 'a', 'b', a);
-	F.temporary.other[cachekey] = fn;
-	fn(obj, value, path);
-};
-
-exports.get = function(obj, path) {
-
-	var cachekey = 'G=' + path;
-
-	if (F.temporary.other[cachekey])
-		return F.temporary.other[cachekey](obj);
-
-	var arr = parsepath(path);
-	var builder = [];
-
-	for (var i = 0, length = arr.length - 1; i < length; i++)
-		builder.push('if(!w' + (!arr[i] || arr[i][0] === '[' ? '' : '.') + arr[i] + ')return');
-
-	var v = arr[arr.length - 1];
-	var fn = (new Function('w', builder.join(';') + ';return w' + (v[0] === '[' ? '' : '.') + v));
-	F.temporary.other[cachekey] = fn;
-	return fn(obj);
-};
-
-function parsepath(path) {
-
-	var arr = path.split('.');
-	var builder = [];
-	var all = [];
-
-	for (var i = 0; i < arr.length; i++) {
-		var p = arr[i];
-		var index = p.indexOf('[');
-		if (index === -1) {
-			if (p.indexOf('-') === -1) {
-				all.push(p);
-				builder.push(all.join('.'));
-			} else {
-				var a = all.splice(all.length - 1);
-				all.push(a + '[\'' + p + '\']');
-				builder.push(all.join('.'));
-			}
-		} else {
-			if (p.indexOf('-') === -1) {
-				all.push(p.substring(0, index));
-				builder.push(all.join('.'));
-				all.splice(all.length - 1);
-				all.push(p);
-				builder.push(all.join('.'));
-			} else {
-				all.push('[\'' + p.substring(0, index) + '\']');
-				builder.push(all.join(''));
-				all.push(p.substring(index));
-				builder.push(all.join(''));
-			}
-		}
-	}
-
-	return builder;
-}
-
-global.sync = exports.sync;
-global.sync2 = exports.sync2;
-
 // =============================================
 // SHELL SORT IMPLEMENTATION OF ALGORITHM
 // =============================================
 
 function _shellInsertionSort(list, length, gapSize, fn) {

Vulnerable code: exports.sync = function(fn, owner) {
	return function() {

		var args = [].slice.call(arguments);
		var params;
		var callback;
		var executed = false;
		var self = owner || this;

		args.push(function() {
			params = arguments;
			if (!executed && callback) {
				executed = true;
				callback.apply(self, params);
			}
		});

		fn.apply(self, args);

		return function(cb) {
			callback = cb;
			if (!executed && params) {
				executed = true;
				callback.apply(self, params);
			}
		};
	};
};

exports.sync2 = function(fn, owner) {
	return (function() {

		var params;
		var callback;
		var executed = false;
		var self = owner || this;
		var args = [].slice.call(arguments);

		args.push(function() {
			params = arguments;
			if (!executed && callback) {
				executed = true;
				callback.apply(self, params);
			}
		});

		fn.apply(self, args);

		return function(cb) {
			callback = cb;
			if (!executed && params) {
				executed = true;
				callback.apply(self, params);
			}
		};
	})();
};

exports.set = function(obj, path, value) {
	var cachekey = 'S+' + path;

	if (F.temporary.other[cachekey])
		return F.temporary.other[cachekey](obj, value);

	var arr = parsepath(path);
	var builder = [];

	for (var i = 0; i < arr.length - 1; i++) {
		var type = arr[i + 1] ? (REGISARR.test(arr[i + 1]) ? '[]' : '{}') : '{}';
		var p = 'w' + (arr[i][0] === '[' ? '' : '.') + arr[i];
		builder.push('if(typeof(' + p + ')!==\'object\'||' + p + '==null)' + p + '=' + type + ';');
	}

	var v = arr[arr.length - 1];
	var ispush = v.lastIndexOf('[]') !== -1;
	var a = builder.join(';') + ';var v=typeof(a)===\'function\'?a(U.get(b)):a;w' + (v[0] === '[' ? '' : '.') + (ispush ? v.replace(REGREPLACEARR, '.push(v)') : (v + '=v')) + ';return v';

	if ((/__proto__|constructor|prototype|eval/).test(a))
		throw new Error('Potential vulnerability');

	var fn = new Function('w', 'a', 'b', a);
	F.temporary.other[cachekey] = fn;
	fn(obj, value, path);
};

exports.get = function(obj, path) {

	var cachekey = 'G=' + path;

	if (F.temporary.other[cachekey])
		return F.temporary.other[cachekey](obj);

	var arr = parsepath(path);
	var builder = [];

	for (var i = 0, length = arr.length - 1; i < length; i++)
		builder.push('if(!w' + (!arr[i] || arr[i][0] === '[' ? '' : '.') + arr[i] + ')return');

	var v = arr[arr.length - 1];
	var fn = (new Function('w', builder.join(';') + ';return w' + (v[0] === '[' ? '' : '.') + v));
	F.temporary.other[cachekey] = fn;
	return fn(obj);
};

function parsepath(path) {

	var arr = path.split('.');
	var builder = [];
	var all = [];

	for (var i = 0; i < arr.length; i++) {
		var p = arr[i];
		var index = p.indexOf('[');
		if (index === -1) {
			if (p.indexOf('-') === -1) {
				all.push(p);
				builder.push(all.join('.'));
			} else {
				var a = all.splice(all.length - 1);
				all.push(a + '[\'' + p + '\']');
				builder.push(all.join('.'));
			}
		} else {
			if (p.indexOf('-') === -1) {
				all.push(p.substring(0, index));
				builder.push(all.join('.'));
				all.splice(all.length - 1);
				all.push(p);
				builder.push(all.join('.'));
			} else {
				all.push('[\'' + p.substring(0, index) + '\']');
				builder.push(all.join(''));
				all.push(p.substring(index));
				builder.push(all.join(''));
			}
		}
	}

	return builder;
}

global.sync = exports.sync;
global.sync2 = exports.sync2;

Fixed code: - removed method `U.set()`
- removed method `U.get()`
- removed method `U.sync()` and `global.sync()`
- removed method `U.sync2()` and `global.sync2()`