Apr 11, 2026·5 min read·1 visit
A sandbox bypass in mathjs < 15.2.0 allows low-privileged attackers to execute arbitrary JavaScript code via crafted expressions. The flaws involve array method shadowing and type confusion, resulting in a CVSS score of 8.8. Immediate upgrade to version 15.2.0 is required.
The mathjs library prior to version 15.2.0 contains critical vulnerabilities in its expression parser sandbox. An attacker can leverage improper property validation and type confusion to execute arbitrary JavaScript within the host environment. The issue stems from lenient array property validation and inadequate type checking on the index parameter during dimension evaluation.
The mathjs library provides an extensive mathematical expression parser designed to evaluate inputs safely within JavaScript and Node.js environments. To prevent untrusted input from accessing sensitive global objects, mathjs implements a custom sandbox. This sandbox restricts access to properties and methods that could be abused to execute arbitrary code.
Two critical flaws exist within this sandbox implementation in versions prior to 15.2.0. The first vulnerability involves improper property validation that allows an attacker to shadow native array methods. The second vulnerability is a type confusion flaw within the indexing utilities that permits the injection of malicious duck-typed objects.
These vulnerabilities are classified under CWE-915 (Improperly Controlled Modification of Dynamically-Determined Object Attributes). Because mathjs executes within the context of the host application, a successful sandbox bypass typically results in remote code execution (RCE) on server-side Node.js environments. The CVSS 3.0 vector evaluates to 8.8 due to the low privilege requirements and the complete compromise of confidentiality, integrity, and availability.
The first execution pathway exploits the isSafeProperty validation function within the mathjs expression parser. Prior to version 15.2.0, this function utilized a blacklist approach to restrict property access during evaluation. The blacklist explicitly targeted properties located on Object.prototype and Function.prototype to prevent prototype pollution and subsequent execution escapes.
This validation strategy failed to properly distinguish between standard Objects and Arrays. The lack of specific isolation for Array.prototype allowed an attacker to define native array methods as "own-properties" directly on an array instance. Methods such as map, reduce, or push could be successfully shadowed by malicious functions.
When the internal logic of mathjs subsequently invoked these shadowed methods on the poisoned array object, the JavaScript engine executed the attacker-controlled function rather than the native implementation. This control flow hijack provided a reliable pathway to retrieve the global Function constructor, bypassing the sandbox restrictions entirely.
The second execution pathway leverages a type confusion flaw within the get function located in src/utils/array.js. This function is responsible for evaluating matrix and array indices during expression processing. Prior to version 15.2.0, the function lacked strict type validation for its index parameter.
Because the parameter was not strictly validated as a native JavaScript Array, an attacker could supply a duck-typed object. This malicious object merely needed to satisfy the expected property checks, such as exposing a length property, to pass the initial validation routines. The object could then be constructed to include a custom reduce method containing a malicious payload.
During dimension validation, mathjs iterates over the provided indices using the reduce method. Invoking this method on the attacker-supplied duck-typed object triggered the embedded payload. This execution occurred during internal processing, bypassing the expression parser's standard safety boundaries.
Exploitation requires the attacker to supply a crafted string to the math.evaluate() or math.parse() functions within a vulnerable application. No user interaction is required, and network access is sufficient if the application exposes the mathjs evaluation endpoint via a web API.
The Array Method Shadowing attack involves instantiating an ArrayNode and extracting the underlying JavaScript array. The attacker overrides the map method on this array to inject a custom function. By passing this poisoned array to a FunctionAssignmentNode, the execution flow extracts the global Function constructor.
The Duck-Typed Index Injection attack directly targets the matrix get method. The attacker creates a matrix and invokes its get method, supplying an object literal instead of a valid index array. When mathjs validates the matrix dimensions, it executes the injected reduce function, returning a reference to process in Node.js.
// Proof of Concept: Duck-Typed Index Injection
m = matrix();
// Supply duck-typed object to bypass Array validation
func = m.get({"length":1,"reduce":f(callback,a)=callback(cos,"constructor")});
// Obtain global Function constructor and execute
getProcess = func("return process");
getProcess()The vulnerabilities were resolved in commit 0aee2f61866e35ffa0aef915221cdf6b026ffdd4 (PR #3656), which introduced strict validation mechanisms. The primary architectural change involved deprecating the generic isSafeProperty function. The maintainers replaced it with context-specific validators named isSafeObjectProperty and isSafeArrayProperty.
The new isSafeArrayProperty function implements a strict whitelist for array access. It permits access exclusively to numeric indices and the literal .length property. This structural change entirely prevents attackers from shadowing executable methods like map and reduce, closing the first execution pathway.
To resolve the type confusion vulnerability, the patch introduced explicit Array.isArray(index) checks. These checks enforce strict type validation within src/utils/array.js and the matrix get methods. Duck-typed objects are now rejected immediately before dimension validation occurs.
The implementation of these whitelist and strict typing mechanisms provides a robust defense against sandbox evasion. The patch eliminates the known execution vectors and significantly reduces the attack surface for future bypass attempts.
The primary and only definitive remediation strategy is upgrading the mathjs dependency. Development teams must update their package.json files to specify version 15.2.0 or later. Applications must be redeployed to ensure the patched library is active in the runtime environment.
There are no viable configuration workarounds to secure vulnerable versions of mathjs. The application of the patch is mandatory for any software relying on the library to process untrusted mathematical expressions.
Security operations teams can implement detection mechanisms while patches are deployed. Web Application Firewalls (WAFs) and monitoring solutions should flag requests containing mathjs expressions that utilize reviver, toJSON, or attempt to override array methods. Monitoring for access to the constructor property within mathjs inputs is also highly recommended.
CVSS:3.0/AV:N/AC:L/PR:L/UI:N/S:U/C:H/I:H/A:H| Product | Affected Versions | Fixed Version |
|---|---|---|
mathjs josdejong | < 15.2.0 | 15.2.0 |
| Attribute | Detail |
|---|---|
| CWE ID | CWE-915 |
| Attack Vector | Network |
| CVSS Base Score | 8.8 |
| Impact | Remote Code Execution |
| Exploit Status | Proof of Concept |
| Remediation | Patch Available |
Improperly Controlled Modification of Dynamically-Determined Object Attributes