VYPR
Critical severityNVD Advisory· Published Mar 6, 2024· Updated Aug 13, 2024

JSONata expression can pollute the "Object" prototype

CVE-2024-27307

Description

In JSONata before 1.8.7 and 2.0.4, the transform operator allows overriding Object prototype properties, potentially leading to denial of service or remote code execution.

AI Insight

LLM-synthesized narrative grounded in this CVE's description and references.

In JSONata before 1.8.7 and 2.0.4, the transform operator allows overriding Object prototype properties, potentially leading to denial of service or remote code execution.

Vulnerability

Overview

JSONata, a JSON query and transformation language, is vulnerable to prototype pollution via its transform operator in versions 1.4.0 through 1.8.6 and 2.0.0 through 2.0.3 [1][2]. A malicious expression can override properties on the Object constructor and prototype, polluting built-in JavaScript objects [2].

Exploitation

The attack surface includes any application that evaluates user-provided JSONata expressions without sanitization [2]. An attacker can craft a JSONata expression that uses the transform operator to set properties like __proto__ or constructor.prototype, thereby injecting malicious properties that affect all objects [2]. No authentication is required if the expression input is exposed to users.

Impact

Successful exploitation can lead to denial of service, remote code execution, or other unexpected behavior due to the alteration of object prototypes [1][2]. The exact impact depends on how the application uses JSONata and the JavaScript runtime environment.

Mitigation

The issue is patched in JSONata versions 1.8.7 and 2.0.4 [2][3]. Applications evaluating user expressions should update immediately. If updating is not possible, a manual patch (shown in the advisory) can be applied to block writes to prototype and constructor properties [2][4].

AI Insight generated on May 20, 2026. Synthesized from this CVE's description and the cited reference URLs; citations are validated against the source bundle.

Affected packages

Versions sourced from the GitHub Security Advisory.

PackageAffected versionsPatched versions
jsonatanpm
>= 1.4.0, < 1.8.71.8.7
jsonatanpm
>= 2.0.0, < 2.0.42.0.4

Affected products

4

Patches

3
1d579dbe99c1

Prevent writing to the object prototype or constructor (v1 port) (#681)

https://github.com/jsonata-js/jsonataMatt BaileyMar 1, 2024via ghsa
2 files changed · +35 1
  • src/jsonata.js+9 1 modified
    @@ -1295,6 +1295,13 @@ var jsonata = (function() {
                     }
                     for(var ii = 0; ii < matches.length; ii++) {
                         var match = matches[ii];
    +                    if (match && (match.isPrototypeOf(result) || match instanceof Object.constructor)) {
    +                        throw {
    +                            code: "D1010",
    +                            stack: (new Error()).stack,
    +                            position: expr.position
    +                        };
    +                    }
                         // evaluate the update value for each match
                         var update = yield * evaluate(expr.update, match, environment);
                         // update must be an object
    @@ -1539,7 +1546,7 @@ var jsonata = (function() {
                     if (typeof err.token == 'undefined' && typeof proc.token !== 'undefined') {
                         err.token = proc.token;
                     }
    -                err.position = proc.position;
    +                err.position = proc.position || err.position;
                 }
                 throw err;
             }
    @@ -1971,6 +1978,7 @@ var jsonata = (function() {
             "T1007": "Attempted to partially apply a non-function. Did you mean ${{{token}}}?",
             "T1008": "Attempted to partially apply a non-function",
             "D1009": "Multiple key definitions evaluate to same key: {{value}}",
    +        "D1010": "Attempted to access the Javascript object prototype", // Javascript specific 
             "T1010": "The matcher function argument passed to function {{token}} does not return the correct object structure",
             "T2001": "The left side of the {{token}} operator must evaluate to a number",
             "T2002": "The right side of the {{token}} operator must evaluate to a number",
    
  • test/implementation-tests.js+26 0 modified
    @@ -806,6 +806,32 @@ describe("Tests that are specific to a Javascript runtime", () => {
                 });
             });
         });
    +    describe("Expressions that attempt to pollute the object prototype", function() {
    +        it("should throw an error with __proto__", async function() {
    +            const expr = jsonata('{} ~> | __proto__ | {"is_admin": true} |');
    +            expect(function() {
    +                expr.evaluate();
    +            })
    +                .to.throw()
    +                .to.deep.contain({ position: 7, code: "D1010" });
    +        });
    +        it("should throw an error with __lookupGetter__", async function() {
    +            const expr = jsonata('{} ~> | __lookupGetter__("__proto__")() | {"is_admin": true} |');
    +            expect(function() {
    +                expr.evaluate();
    +            })
    +                .to.throw()
    +                .to.deep.contain({ position: 7, code: "D1010" });
    +        });
    +        it("should throw an error with constructor", async function() {
    +            const expr = jsonata('{} ~> | constructor | {"is_admin": true} |');
    +            expect(function() {
    +                expr.evaluate();
    +            })
    +                .to.throw()
    +                .to.deep.contain({ position: 7, code: "D1010" });
    +        });
    +    });
     });
     
     describe("Test that yield platform specific results", () => {
    
335d38f6278e

Check for constructor property

2 files changed · +10 1
  • src/jsonata.js+1 1 modified
    @@ -1293,7 +1293,7 @@ var jsonata = (function() {
                     }
                     for(var ii = 0; ii < matches.length; ii++) {
                         var match = matches[ii];
    -                    if (match && match.isPrototypeOf(result)) {
    +                    if (match && (match.isPrototypeOf(result) || match instanceof Object.constructor)) {
                             throw {
                                 code: "D1010",
                                 stack: (new Error()).stack,
    
  • test/implementation-tests.js+9 0 modified
    @@ -974,6 +974,15 @@ describe("Tests that are specific to a Javascript runtime", () => {
                     code: "D1010",
                 });
             });
    +        it("should throw an error with constructor", async function() {
    +            const expr = jsonata('{} ~> | constructor | {"is_admin": true} |');
    +            expect(
    +                expr.evaluate()
    +            ).to.eventually.be.rejected.to.deep.contain({
    +                position: 7,
    +                code: "D1010",
    +            });
    +        });
         });
     });
     
    
c907b5e517bb

Prevent access to __proto__

https://github.com/jsonata-js/jsonataandrew-colemanFeb 27, 2024via ghsa
2 files changed · +29 1
  • src/jsonata.js+9 1 modified
    @@ -1293,6 +1293,13 @@ var jsonata = (function() {
                     }
                     for(var ii = 0; ii < matches.length; ii++) {
                         var match = matches[ii];
    +                    if (match && match.isPrototypeOf(result)) {
    +                        throw {
    +                            code: "D1010",
    +                            stack: (new Error()).stack,
    +                            position: expr.position
    +                        };
    +                    }
                         // evaluate the update value for each match
                         var update = await evaluate(expr.update, match, environment);
                         // update must be an object
    @@ -1539,7 +1546,7 @@ var jsonata = (function() {
                     if (typeof err.token == 'undefined' && typeof proc.token !== 'undefined') {
                         err.token = proc.token;
                     }
    -                err.position = proc.position;
    +                err.position = proc.position || err.position;
                 }
                 throw err;
             }
    @@ -1972,6 +1979,7 @@ var jsonata = (function() {
             "T1007": "Attempted to partially apply a non-function. Did you mean ${{{token}}}?",
             "T1008": "Attempted to partially apply a non-function",
             "D1009": "Multiple key definitions evaluate to same key: {{value}}",
    +        "D1010": "Attempted to access the Javascript object prototype", // Javascript specific 
             "T1010": "The matcher function argument passed to function {{token}} does not return the correct object structure",
             "T2001": "The left side of the {{token}} operator must evaluate to a number",
             "T2002": "The right side of the {{token}} operator must evaluate to a number",
    
  • test/implementation-tests.js+20 0 modified
    @@ -955,6 +955,26 @@ describe("Tests that are specific to a Javascript runtime", () => {
                 });
             });
         });
    +    describe("Expressions that attempt to pollute the object prototype", function() {
    +        it("should throw an error with __proto__", async function() {
    +            const expr = jsonata('{} ~> | __proto__ | {"is_admin": true} |');
    +            expect(
    +                expr.evaluate()
    +            ).to.eventually.be.rejected.to.deep.contain({
    +                position: 7,
    +                code: "D1010",
    +            });
    +        });
    +        it("should throw an error with __lookupGetter__", async function() {
    +            const expr = jsonata('{} ~> | __lookupGetter__("__proto__")() | {"is_admin": true} |');
    +            expect(
    +                expr.evaluate()
    +            ).to.eventually.be.rejected.to.deep.contain({
    +                position: 7,
    +                code: "D1010",
    +            });
    +        });
    +    });
     });
     
     describe("Test that yield platform specific results", () => {
    

Vulnerability mechanics

Generated on May 9, 2026. Inputs: CWE entries + fix-commit diffs from this CVE's patches. Citations validated against bundle.

References

7

News mentions

0

No linked articles in our index yet.