Skip to main content
CVE Vulnerability Database
Vulnerability Database/CVE-2026-12866

CVE-2026-12866: expr-eval Package RCE Vulnerability

CVE-2026-12866 is a remote code execution flaw in the expr-eval package affecting all versions. Attackers exploit the toJSFunction() API to execute arbitrary code. This article covers technical details, impact, and mitigations.

Published:

CVE-2026-12866 Overview

CVE-2026-12866 affects all versions of the expr-eval JavaScript package, a popular math expression parser used in Node.js applications. The vulnerability exists in the toJSFunction() API, which compiles user-supplied expressions into native JavaScript using the new Function() constructor. Attackers can craft expressions that escape the intended sandbox and execute arbitrary JavaScript within the host application's context. The flaw maps to CWE-94: Improper Control of Generation of Code.

Critical Impact

Remote attackers can achieve arbitrary code execution in any application that passes untrusted input to expr-eval's toJSFunction(), leading to full server compromise.

Affected Products

  • expr-eval npm package — all versions
  • Node.js applications that invoke toJSFunction() with attacker-influenced input
  • Downstream packages and services bundling expr-eval as a dependency

Discovery Timeline

  • 2026-06-23 - CVE-2026-12866 published to the National Vulnerability Database
  • 2026-06-23 - Last updated in NVD database

Technical Details for CVE-2026-12866

Vulnerability Analysis

The expr-eval library markets itself as a safer alternative to eval() for evaluating math expressions. However, the toJSFunction() API breaks that assumption. Instead of interpreting expressions through the library's internal AST evaluator, this function concatenates the parsed expression into a string and passes it to new Function(). The resulting native function executes inside the calling process with full JavaScript privileges.

The expression sandbox does not enforce a safe character or token allow-list before code generation. Attackers can inject JavaScript constructs that survive the parser and reach the dynamic compilation step. Once new Function() runs the crafted payload, the attacker controls execution in the application's context.

Root Cause

The root cause is improper code generation [CWE-94]. The library transforms user-controlled expressions directly into executable JavaScript without isolating them from the host runtime. Use of new Function() on attacker-influenced strings collapses the intended boundary between data and code.

Attack Vector

The vulnerability is network-exploitable when an application exposes an HTTP endpoint, message handler, or API that forwards user input to toJSFunction(). No authentication or user interaction is required if the vulnerable endpoint is publicly reachable. Common exposure patterns include formula evaluators, reporting tools, calculator services, and rule engines that accept expressions from end users. The vulnerability mechanism and proof points are discussed in the GitHub Issue #292 Discussion and the Snyk advisory SNYK-JS-EXPREVAL-15054690.

No verified public proof-of-concept code is provided in the advisory. The exploitation pattern is documented in the expression evaluation source code, where the toJSFunction() implementation builds a string and invokes new Function() on it.

Detection Methods for CVE-2026-12866

Indicators of Compromise

  • Unexpected child processes spawned by Node.js runtimes, such as sh, bash, cmd.exe, or powershell.exe
  • Outbound connections from Node.js application servers to unfamiliar hosts shortly after expression-evaluation API calls
  • Application logs showing unusually long, malformed, or syntactically suspicious expression payloads submitted to evaluator endpoints
  • Filesystem writes or reads by Node.js processes outside of expected application directories

Detection Strategies

  • Inventory all uses of expr-eval across application source and package-lock.json files, then identify every call site invoking toJSFunction()
  • Add static analysis rules that flag any code path passing request-derived data into toJSFunction() or Parser.parse(...).toJSFunction()
  • Inspect runtime telemetry for Node.js processes invoking child_process, fs, or network APIs immediately following expression-evaluation traffic

Monitoring Recommendations

  • Forward Node.js application and process telemetry into a centralized analytics platform to correlate expression input with subsequent process or network activity
  • Alert on new Function() invocations originating from request handlers in environments where dynamic compilation is unexpected
  • Track dependency graphs for the expr-eval package and trigger alerts when a patched version becomes available upstream

How to Mitigate CVE-2026-12866

Immediate Actions Required

  • Audit all application code for calls to toJSFunction() and remove them where untrusted input can reach the function
  • Replace toJSFunction() with the library's interpreted evaluate() method, which does not invoke new Function()
  • Apply strict input validation that rejects any expression containing identifiers, property accessors, or characters outside an arithmetic allow-list
  • Treat the expr-eval dependency as deprecated for any use case involving user-controlled expressions and plan migration to a hardened expression evaluator

Patch Information

At the time of publication, no fixed version of expr-eval is listed in the advisory. Because all versions are affected, organizations must remove or replace the dependency, or eliminate use of toJSFunction() until an upstream patch is released. Track remediation status through the Snyk advisory SNYK-JS-EXPREVAL-15054690 and GitHub Issue #292 Discussion.

Workarounds

  • Switch evaluation calls from parser.parse(expr).toJSFunction(vars) to parser.parse(expr).evaluate(scope) to avoid new Function() compilation
  • Run expression evaluation inside an isolated worker or sandboxed VM context with no access to require, process, or filesystem APIs
  • Enforce a server-side allow-list of permitted operators, function names, and variable identifiers before passing input to the parser
  • Apply egress network controls on application hosts so that successful code execution cannot easily reach attacker infrastructure
bash
# Configuration example: safer evaluation pattern
# Replace vulnerable toJSFunction() usage
# const fn = parser.parse(userInput).toJSFunction(['x']);  // vulnerable
# const result = fn(value);

# With interpreted evaluation against a fixed scope
# const result = parser.parse(userInput).evaluate({ x: value });

Disclaimer: This content was generated using AI. While we strive for accuracy, please verify critical information with official sources.

Default Legacy - Prefooter | Experience the World’s Most Advanced Cybersecurity Platform

Experience the Most Advanced Cybersecurity Platform

See how the world’s most intelligent, autonomous cybersecurity platform can protect your organization today and into the future.