VYPR
Critical severityNVD Advisory· Published Jul 12, 2021· Updated Sep 17, 2024

Arbitrary Code Execution

CVE-2021-23390

Description

Arbitrary code execution in total4 before 0.0.43 via U.set() and U.get() functions.

AI Insight

LLM-synthesized narrative grounded in this CVE's description and references.

Arbitrary code execution in total4 before 0.0.43 via U.set() and U.get() functions.

Vulnerability

The total4 package for Node.js (versions before 0.0.43) is vulnerable to arbitrary code execution through the U.set() and U.get() functions. The vulnerability arises because these functions evaluate specially crafted path strings, allowing injection of arbitrary JavaScript code. The affected versions are those prior to 0.0.43 [1][3].

Exploitation

An attacker can exploit this vulnerability by invoking U.set() or U.get() with a maliciously crafted path string. No authentication is required if the application passes user-controlled input to these functions. The following proof-of-concept demonstrates code execution: U.set({}, 'a;let {mainModule}=process; let {require}=mainModule; let {exec}=require("child_process"); exec("touch HACKED")//', value); [3].

Impact

Successful exploitation allows an attacker to execute arbitrary commands on the server, leading to full compromise of the application and underlying system, including data disclosure, modification, or denial of service.

Mitigation

The vulnerability is fixed in version 0.0.43 [3]. Users should upgrade to total4 version 0.0.43 or later. The fix involved removing the vulnerable U.set() and U.get() functions entirely [2]. No workarounds are available for earlier versions.

AI Insight generated on May 21, 2026. Synthesized from this CVE's description and the cited reference URLs; citations are validated against the source bundle.

Affected packages

Versions sourced from the GitHub Security Advisory.

PackageAffected versionsPatched versions
total4npm
< 0.0.430.0.43

Affected products

2

Patches

1
8a72d8c20f38

Removed useless methods.

https://github.com/totaljs/framework4Peter ŠirkaJun 4, 2021via ghsa
2 files changed · +4 144
  • changelog.txt+4 0 modified
    @@ -3,6 +3,10 @@
     ========================
     
     - 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
    
  • utils.js+0 144 modified
    @@ -5203,64 +5203,6 @@ 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) {
    @@ -5475,92 +5417,6 @@ exports.parseTheme = function(value) {
     	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
     // =============================================
    

Vulnerability mechanics

Generated on May 9, 2026. Inputs: CWE entries + fix-commit diffs from this CVE's patches. Citations validated against bundle.

References

5

News mentions

0

No linked articles in our index yet.