TL;DR

JSONata — a 1.3M-weekly-download npm package that workflow-automation platforms (most notably n8n, which ships it as a first-class expression language) and other AI-agent/low-code tools embed specifically because it's marketed as a safe, sandboxed way to let users write data-transformation expressions — shipped two critical arbitrary-code-execution advisories on the same day: CVE-2026-77414 (GHSA-2943-5xfg-gq5f) and CVE-2026-77415 (GHSA-66mm-25pp-rfff), both CVSS 9.3 (v4.0) / 9.8 (v3.1). A crafted JSONata expression — the exact kind of untrusted input the library exists to evaluate — escapes the evaluation sandbox and runs arbitrary Node.js code. Fixed in 1.8.8 and 2.2.1.

What happened

JSONata is a JSON query-and-transformation language, and its whole value proposition to embedders is that user-supplied expressions can be evaluated without giving the expression author access to the host JavaScript environment — the same "safe sandbox for untrusted expressions" pitch that vm2 and isolated-vm make (see the vm2/isolated-vm sandbox-escape advisory), just implemented as a language interpreter rather than a V8 isolate. Both new CVEs break that promise, discovered and reported by researcher c0rydoras, published to GHSA/NVD 2026-08-21 (originally filed 2026-07-13):

  • CVE-2026-77414 (GHSA-2943-5xfg-gq5f) — a bypassable hasOwnProperty check in environment.lookup. The environment-lookup function is supposed to confine name resolution to the sandbox's own scope, but the check can be defeated by shadowing local lookup methods and walking the prototype chain, letting a crafted expression reach host-realm objects and functions it was never meant to see.
  • CVE-2026-77415 (GHSA-66mm-25pp-rfff) — three chainable weaknesses in the same evaluator: overwriting the built-in $clone function lets an expression mutate objects during a transform instead of only copying them; JSONata functions/lambdas can be destructured (e.g. via $merge.*) to expose their internals; and applyProcedure's custom forEach-style argument handling (rather than Array.prototype.forEach) gives a crafted expression a way to manipulate proc.arguments. Chained together, these let an attacker escape the evaluation environment and execute arbitrary system commands through the Node.js runtime.

Both bugs share the same root shape as the vm2/isolated-vm cluster tracked in this repo three weeks earlier: a component that markets itself as a safe way to run untrusted, model- or user-supplied input turns out not to be one, and because neither is a lifecycle-script or install-time issue, standard --ignore-scripts / supply-chain hygiene does nothing to stop it — the vulnerable code only runs when the application evaluates an expression, which is JSONata's entire purpose.

Am I affected?

# Direct or transitive dependency on jsonata, and at what version?
npm ls jsonata --all 2>/dev/null
# Or from a lockfile:
grep -n -A2 '"jsonata"' package-lock.json 2>/dev/null | head -40

Fixed versions: 1.8.8 and 2.2.1. Anything < 1.8.8 or >= 2.0.0, < 2.2.1 is affected.

If you run n8n, check whether your build has already picked up the patched jsonata via its own dependency updates — n8n embeds JSONata as a built-in expression mode, so any workflow that accepts a JSONata expression from an untrusted source (a webhook payload, a form submission, another tenant) is a direct attack surface until the transitive dependency is bumped. The same applies to any other platform that lets users author JSONata expressions — treat "we sandbox user expressions with JSONata" the same way you'd treat "we sandbox user code with vm2": as a mitigation that just failed, not a boundary.

If you are affected

Prevention

Practical guidance: put an OS-level boundary (container, VM, seccomp, separate process with dropped privileges) beneath any embedded expression/query-language evaluator that processes untrusted input, exactly as recommended for vm2/isolated-vm — an in-language "safe expression" sandbox is not a substitute for process isolation. Watch GHSA and your platform's dependency-bump changelogs directly; a transitive jsonata upgrade will rarely be called out as a security fix in the embedding platform's own release notes.

Sources