Arbitrary Code Execution
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.
| Package | Affected versions | Patched versions |
|---|---|---|
total4npm | < 0.0.43 | 0.0.43 |
Affected products
2- total4/total4description
Patches
18a72d8c20f38Removed useless methods.
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- github.com/advisories/GHSA-g7mq-rfj2-25wqghsaADVISORY
- nvd.nist.gov/vuln/detail/CVE-2021-23390ghsaADVISORY
- github.com/totaljs/framework4/blob/master/utils.js%23L5430-L5455ghsax_refsource_MISCWEB
- github.com/totaljs/framework4/commit/8a72d8c20f38bbcac031a76a51238aa528f68821ghsax_refsource_MISCWEB
- snyk.io/vuln/SNYK-JS-TOTAL4-1130527ghsax_refsource_MISCWEB
News mentions
0No linked articles in our index yet.