CVEReports
CVEReports

Automated vulnerability intelligence platform. Comprehensive reports for high-severity CVEs generated by AI.

Product

  • Home
  • Sitemap
  • RSS Feed

Company

  • About
  • Contact
  • Privacy Policy
  • Terms of Service

© 2026 CVEReports. All rights reserved.

Made with love by Amit Schendel & Alon Barad



CVE-2026-32304
9.80.08%

CVE-2026-32304: Remote Code Execution via Code Injection in Locutus create_function

Amit Schendel
Amit Schendel
Senior Security Researcher

Mar 13, 2026·5 min read·3 visits

PoC Available

Executive Summary (TL;DR)

Unsanitized input passed to the new Function() constructor in Locutus create_function allows attackers to execute arbitrary JavaScript code. The vulnerability is fixed in version 3.0.14 by completely removing the vulnerable module.

Locutus versions prior to 3.0.14 contain a critical remote code execution vulnerability in the PHP compatibility layer. The create_function implementation improperly constructs dynamic JavaScript functions using unsanitized user input, leading to arbitrary code execution through the Function constructor.

Vulnerability Overview

Locutus provides PHP standard library functions to JavaScript environments. The library includes a port of the legacy PHP create_function utility, intended to dynamically generate callable functions at runtime.

In versions prior to 3.0.14, the implementation of create_function suffers from a CWE-94 (Code Injection) vulnerability. The function accepts two string arguments, args and code, representing the parameters and body of the new function.

The vulnerability arises because these strings are passed directly into the JavaScript new Function() constructor. The lack of input validation or sanitization allows an attacker to break out of the intended function definition and execute arbitrary JavaScript code within the context of the host application.

Root Cause Analysis

The root cause of CVE-2026-32304 is the unsafe use of a dynamic code evaluation sink. In JavaScript, the Function constructor evaluates string arguments as executable code in the global scope, operating similarly to the eval() function.

The vulnerable module, src/php/funchand/create_function.ts, takes the user-provided args string, splits it by commas, and spreads the resulting array into the Function constructor alongside the code string. Neither input is checked for malicious payloads or structural integrity.

Because the JavaScript engine parses the dynamically constructed string as an actual function, an attacker can manipulate the syntax to terminate the parameter list early or inject arbitrary logic into the function body. Once the resulting function object is invoked by the application, the injected payload executes immediately.

Code Analysis

The vulnerable implementation demonstrates a direct path from the function arguments to the evaluation sink. The create_function signature accepts args and code as strings.

// src/php/funchand/create_function.ts (Vulnerable Version)
export function create_function(args: string, code: string): PhpCallable | false {
  try {
    const params = args
      .split(',')
      .map((param) => param.trim())
      .filter((param) => param.length > 0);
 
    const created = new Function(...params, code);
    return (...callArgs: PhpInput[]) => Reflect.apply(created, null, callArgs);
  } catch (_e) {
    return false;
  }
}

The patch applied in version 3.0.14 entirely removes this file. The maintainers recognized that simulating PHP's create_function safely in JavaScript is not feasible without complex abstract syntax tree parsing, and the upstream PHP language itself removed the function in PHP 8.0.

The secondary file src/php/var/var_export.ts was also updated in commit 412fdb17b9b0138023eae0b32d2519ee6c547661. Previously, it utilized create_function to serialize functions. The patch replaces this dynamically generated function with a static stub: \Closure::__set_state(array()).

Execution Flow

The data flow path demonstrates how user input reaches the execution sink without validation.

This execution chain requires the application to actively call the function returned by create_function. The payload compilation happens during the constructor call, but execution is deferred until invocation.

Exploitation Mechanics

Exploitation requires the attacker to control the input passed to either the args or code parameters of the create_function utility. The payload structure depends on which parameter is accessible.

If the attacker controls the code parameter, they can inject standard Node.js execution payloads directly. For example, passing return require("child_process").execSync("id").toString() as the code argument causes the resulting function to execute a system shell command upon invocation.

If the attacker controls the args parameter, they must perform a syntax breakout. Supplying a string such as a = 1) { }; process.exit(); // closes the parameter list prematurely, injects the payload, and comments out the remainder of the legitimate function definition.

Impact Assessment

Successful exploitation grants the attacker arbitrary code execution capabilities within the context of the JavaScript runtime environment. The specific consequences depend heavily on where the Locutus library is deployed.

In a Node.js server environment, the attacker can leverage built-in modules like child_process or fs to execute operating system commands, read sensitive files, or establish a reverse shell. This leads to a complete compromise of confidentiality, integrity, and availability.

In a client-side browser environment, the vulnerability functions as a severe Cross-Site Scripting (XSS) vector. An attacker can access sensitive session tokens, manipulate the Document Object Model (DOM), or perform actions on behalf of the user.

Remediation Strategy

The primary remediation for CVE-2026-32304 is upgrading the Locutus library to version 3.0.14 or later. This release permanently removes the create_function utility from the codebase.

Applications relying on locutus/php/funchand/create_function will encounter runtime errors after upgrading. Developers must refactor their application logic to use standard JavaScript anonymous functions or arrow functions instead of dynamically generating them from strings.

To detect potential exploitation attempts prior to patching, security teams can audit codebases for calls to create_function and trace the origin of the inputs. Static analysis tools and linters configured to detect new Function() invocations flag similar vulnerabilities in custom application code.

Official Patches

LocutusRelease Notes for version 3.0.14

Fix Analysis (1)

Technical Appendix

CVSS Score
9.8/ 10
CVSS:3.1/AV:N/AC:L/PR:N/UI:N/S:U/C:H/I:H/A:H
EPSS Probability
0.08%
Top 77% most exploited

Affected Systems

Node.js server applications utilizing LocutusClient-side web applications utilizing Locutus

Affected Versions Detail

Product
Affected Versions
Fixed Version
Locutus
locutusjs
< 3.0.143.0.14
AttributeDetail
CWE IDCWE-94
Attack VectorNetwork
CVSS Score9.8
EPSS Score0.00078
ImpactRemote Code Execution
Exploit StatusPoC Available
CISA KEVNo

MITRE ATT&CK Mapping

T1059.007Command and Scripting Interpreter: JavaScript
Execution
T1190Exploit Public-Facing Application
Initial Access
CWE-94
Code Injection

Improper Control of Generation of Code ('Code Injection')

Vulnerability Timeline

Vulnerability reported and patch developed by Kevin van Zonneveld
2026-03-11
Fix commit 412fdb1 merged to main
2026-03-11
Version 3.0.14 released to npm
2026-03-11
CVE-2026-32304 assigned and GHSA-vh9h-29pq-r5m8 published
2026-03-12
NVD and CVE.org records updated with final metadata
2026-03-13

References & Sources

  • [1]GitHub Security Advisory: GHSA-vh9h-29pq-r5m8
  • [2]Locutus Patch Commit
  • [3]Locutus 3.0.14 Release Notes
  • [4]CVE Record: CVE-2026-32304
Related Vulnerabilities
CVE-2026-29091

Attack Flow Diagram

Press enter or space to select a node. You can then use the arrow keys to move the node around. Press delete to remove it and escape to cancel.
Press enter or space to select an edge. You can then press delete to remove it or escape to cancel.