CVE-2026-1615
Description
Versions of the package jsonpath before 1.3.0 are vulnerable to Arbitrary Code Injection via unsafe evaluation of user-supplied JSON Path expressions. The library relies on the static-eval module to process JSON Path input, which is not designed to handle untrusted data safely. An attacker can exploit this vulnerability by supplying a malicious JSON Path expression that, when evaluated, executes arbitrary JavaScript code, leading to Remote Code Execution in Node.js environments or Cross-site Scripting (XSS) in browser contexts. This affects all methods that evaluate JSON Paths against objects, including .query, .nodes, .paths, .value, .parent, and .apply.
Affected packages
Versions sourced from the GitHub Security Advisory.
| Package | Affected versions | Patched versions |
|---|---|---|
jsonpathnpm | < 1.3.0 | 1.3.0 |
Affected products
1Patches
2b61111f07ac1Merge pull request #197 from dfop02/fix-CVE-2026-1615
2 files changed · +338 −2
lib/handlers.js+151 −2 modified@@ -3,6 +3,152 @@ var slice = require('./slice'); var _evaluate = require('static-eval'); var _uniq = require('underscore').uniq; +// Property names that must never be accessible in expressions. +// Mitigates prototype pollution and constructor escape attacks. +var UNSAFE_PROPERTY_NAMES = Object.create(null); + +/* jshint -W069: true */ +UNSAFE_PROPERTY_NAMES['constructor'] = true; +UNSAFE_PROPERTY_NAMES['__proto__'] = true; +UNSAFE_PROPERTY_NAMES['prototype'] = true; +/* jshint -W069: false */ + +function isUnsafePropertyName(name) { + return typeof name === 'string' && UNSAFE_PROPERTY_NAMES[name] === true; +} + +function isSafeAst(ast) { + if (!ast || typeof ast !== 'object') return false; + + function walk(node) { + if (!node || typeof node !== 'object' || !node.type) { + return false; + } + + switch (node.type) { + + // ===== SAFE TERMINALS ===== + + case 'Literal': + return true; + + case 'Identifier': + // Only allow the special scope identifier + return node.name === '@'; + + + // ===== PROPERTY ACCESS ===== + + case 'MemberExpression': { + if (!walk(node.object)) { + return false; + } + + // Non-computed: obj.property + if (!node.computed && node.property.type === 'Identifier') { + if (isUnsafePropertyName(node.property.name)) { + return false; + } + return true; + } + + // Computed: obj["property"] + if (node.computed) { + if (!walk(node.property)) { + return false; + } + + if ( + node.property.type === 'Literal' && + isUnsafePropertyName(String(node.property.value)) + ) { + return false; + } + + return true; + } + + return false; + } + + + // ===== EXPRESSIONS ===== + + case 'UnaryExpression': + return walk(node.argument); + + case 'BinaryExpression': + case 'LogicalExpression': + return walk(node.left) && walk(node.right); + + case 'ConditionalExpression': + return ( + walk(node.test) && + walk(node.consequent) && + walk(node.alternate) + ); + + case 'ArrayExpression': + for (var i = 0; i < node.elements.length; i++) { + if (!walk(node.elements[i])) { + return false; + } + } + return true; + + case 'ObjectExpression': + for (var j = 0; j < node.properties.length; j++) { + var prop = node.properties[j]; + + // Reject unsafe keys + if ( + prop.key && + ( + (prop.key.type === 'Identifier' && + isUnsafePropertyName(prop.key.name)) || + (prop.key.type === 'Literal' && + isUnsafePropertyName(String(prop.key.value))) + ) + ) { + return false; + } + + if (!walk(prop.value)) { + return false; + } + } + return true; + + + // ===== EXPLICITLY REJECT DANGEROUS TYPES ===== + // Security: do not rely on default deny; list each code-execution / escape vector. + + case 'CallExpression': + case 'NewExpression': + case 'FunctionExpression': + case 'ArrowFunctionExpression': + case 'ThisExpression': + case 'AssignmentExpression': + case 'UpdateExpression': + case 'SequenceExpression': + case 'TemplateLiteral': + case 'TemplateElement': + case 'TaggedTemplateExpression': + case 'ReturnStatement': + case 'ExpressionStatement': + return false; + + + // ===== DEFAULT DENY ===== + + default: + return false; + } + } + + return walk(ast); +} + var Handlers = function() { return this.initialize.apply(this, arguments); } @@ -239,8 +385,11 @@ function _traverse(passable) { } } -function evaluate() { - try { return _evaluate.apply(this, arguments) } +function evaluate(ast, scope) { + if (!isSafeAst(ast)) { + throw new Error('Unsafe expression: script and filter expressions may only access the current node (@) with safe property names'); + } + try { return _evaluate(ast, scope) } catch (e) { } }
test/security.js+187 −0 modified@@ -48,4 +48,191 @@ suite('security', function() { }, /Unsafe key/); assert.equal(({}).polluted, undefined); }); + + suite('CVE-2026-1615: blocks code injection in filter/script expressions', function() { + var data = { a: {}, b: [1, 2, 3] }; + + test('rejects constructor access in filter expression', function() { + assert.throws(function() { + jp.query(data, '$[?(@.constructor)]'); + }, /Unsafe expression/); + }); + + test('rejects constructor.constructor in filter expression', function() { + assert.throws(function() { + jp.query(data, '$[?(@.constructor.constructor)]'); + }, /Unsafe expression/); + }); + + test('rejects chained constructor.constructor call: @.foo["constructor"]["constructor"](...)()', function() { + assert.throws(function() { + jp.query(data, '$[?(@.foo["constructor"]["constructor"]("return process")())]'); + }, /Unsafe expression/); + }); + + test('rejects __proto__ access in filter expression', function() { + assert.throws(function() { + jp.query(data, '$[?(@.__proto__)]'); + }, /Unsafe expression/); + }); + + test('rejects function call in filter expression', function() { + assert.throws(function() { + jp.query(data, '$[?(process.exit(1))]'); + }, /Unsafe expression/); + }); + + test('rejects constructor access in script expression', function() { + var scriptData = { a: [1, 2, 3] }; + assert.throws(function() { + jp.query(scriptData, '$[(@.constructor)]'); + }, /Unsafe expression/); + }); + + test('allows safe filter expressions', function() { + var storeData = { store: { book: [ { price: 5 }, { price: 15 } ] } }; + var results = jp.query(storeData, '$..book[?(@.price<10)]'); + assert.deepEqual(results, [ { price: 5 } ]); + }); + + test('allows safe script expressions', function() { + var bookData = { book: [ { id: 1 }, { id: 2 }, { id: 3 } ] }; + var results = jp.nodes(bookData, '$..book[(@.length-1)]'); + assert.deepEqual(results[0].value, { id: 3 }); + }); + + test('rejects bracket notation constructor: @["constructor"]', function() { + assert.throws(function() { jp.query(data, '$[?(@["constructor"])]'); }, /Unsafe expression/); + }); + + test('rejects bracket notation __proto__: @["__proto__"]', function() { + assert.throws(function() { jp.query(data, '$[?(@["__proto__"])]'); }, /Unsafe expression/); + }); + + test('rejects bracket notation prototype: @["prototype"]', function() { + assert.throws(function() { jp.query(data, '$[?(@["prototype"])]'); }, /Unsafe expression/); + }); + + test('rejects ObjectExpression with unsafe key: { "__proto__": @ }', function() { + assert.throws(function() { jp.query(data, '$[?({ "__proto__": @ })]'); }, /Unsafe expression|Unexpected token/); + }); + + test('rejects ObjectExpression with unsafe key: { "constructor": @ }', function() { + assert.throws(function() { jp.query(data, '$[?({ "constructor": @ })]'); }, /Unsafe expression|Unexpected token/); + }); + + test('rejects ObjectExpression with unsafe key: { "prototype": @ }', function() { + assert.throws(function() { jp.query(data, '$[?({ "prototype": @ })]'); }, /Unsafe expression|Unexpected token/); + }); + + test('rejects unicode escape constructor in bracket: @["\\u0063onstructor"]', function() { + assert.throws(function() { jp.query(data, '$[?(@["\\u0063onstructor"])]'); }, /Unsafe expression/); + }); + + test('rejects unicode escape __proto__ in bracket', function() { + var path = '$[?(@["\\u005f\\u005fproto\\u005f\\u005f"])]'; + assert.throws(function() { jp.query(data, path); }, /Unsafe expression/); + }); + + test('rejects IIFE: (function(){return 1})()', function() { + assert.throws(function() { jp.query(data, '$[?((function(){return 1})())]'); }, /Unsafe expression/); + }); + + test('rejects direct function call: process.exit(1)', function() { + assert.throws(function() { jp.query(data, '$[?(process.exit(1))]'); }, /Unsafe expression/); + }); + + test('rejects require() call', function() { + assert.throws(function() { jp.query(data, '$[?(require("fs"))]'); }, /Unsafe expression/); + }); + + test('rejects eval() call', function() { + assert.throws(function() { jp.query(data, '$[?(eval("1"))]'); }, /Unsafe expression/); + }); + + test('rejects globalThis / global identifier', function() { + assert.throws(function() { jp.query(data, '$[?(globalThis)]'); }, /Unsafe expression/); + assert.throws(function() { jp.query(data, '$[?(global)]'); }, /Unsafe expression/); + }); + + test('rejects NewExpression: new Function("return 1")()', function() { + assert.throws(function() { jp.query(data, '$[?(new Function("return 1")())]'); }, /Unsafe expression/); + }); + + test('rejects JSFuck-style: [] ["filter"]["constructor"]', function() { + assert.throws(function() { jp.query(data, '$[?([]["filter"]["constructor"])]'); }, /Unsafe expression/); + }); + + test('rejects JSFuck-style constructor call (no @)', function() { + assert.throws(function() { jp.query(data, '$[?([]["filter"]["constructor"]("return 1")())]'); }, /Unsafe expression/); + }); + + test('rejects sequence expression: (1, process.exit)(1)', function() { + assert.throws(function() { jp.query(data, '$[?((1, process.exit)(1))]'); }, /Unsafe expression/); + }); + + test('rejects method call on @: @.valueOf()', function() { + assert.throws(function() { jp.query(data, '$[?(@.valueOf())]'); }, /Unsafe expression/); + }); + + test('rejects method call: @.toString()', function() { + assert.throws(function() { jp.query(data, '$[?(@.toString())]'); }, /Unsafe expression/); + }); + + test('rejects template literal in computed: @[`constructor`]', function() { + assert.throws(function() { jp.query(data, '$[?(@[`constructor`])]'); }, /Unsafe expression|Unexpected token|ILLEGAL/); + }); + + test('rejects tagged template (code execution vector)', function() { + assert.throws(function() { jp.query(data, '$[?(String.raw`x`)]'); }, /Unsafe expression|Unexpected token|ILLEGAL/); + }); + + test('rejects ArrowFunctionExpression', function() { + assert.throws(function() { jp.query(data, '$[?((()=>1)())]'); }, /Unsafe expression|Unexpected token/); + }); + + test('rejects ThisExpression (this)', function() { + assert.throws(function() { jp.query(data, '$[?(this)]'); }, /Unsafe expression/); + }); + + test('rejects script expression with constructor', function() { + assert.throws(function() { jp.query(data, '$[(@.constructor)]'); }, /Unsafe expression/); + }); + + test('rejects script expression with call', function() { + assert.throws(function() { jp.query(data, '$[((function(){return 0})())]'); }, /Unsafe expression/); + }); + + test('allows @.length (no call)', function() { + var r = jp.query(data, '$[?(@.length)]'); + assert.ok(Array.isArray(r)); + }); + + test('allows bracket with safe key: @["length"]', function() { + var r = jp.query(data, '$[?(@["length"])]'); + assert.ok(Array.isArray(r)); + }); + + test('allows @["@class"] (existing test pattern)', function() { + var d = { DIV: [{ '@class': 'value', val: 5 }] }; + var r = jp.query(d, '$..DIV[?(@["@class"]=="value")]'); + assert.deepEqual(r, d.DIV); + }); + + test('rejects prototype access in filter', function() { + assert.throws(function() { jp.query(data, '$[?(@.prototype)]'); }, /Unsafe expression/); + }); + + test('rejects comma/sequence that could hide call', function() { + assert.throws(function() { jp.query(data, '$[?((0, eval)("1"))]'); }, /Unsafe expression/); + }); + + test('rejects AssignmentExpression', function() { + assert.throws(function() { jp.query(data, '$[?((x=1)==1)]'); }, /Unsafe expression/); + }); + + test('rejects UpdateExpression (++, --)', function() { + assert.throws(function() { jp.query(data, '$[?(@.x++)]'); }, /Unsafe expression/); + }); + }); });
491e2e01de2fAttempt to fix CVE-2026-1615 vulnerability
2 files changed · +338 −2
lib/handlers.js+151 −2 modified@@ -3,6 +3,152 @@ var slice = require('./slice'); var _evaluate = require('static-eval'); var _uniq = require('underscore').uniq; +// Property names that must never be accessible in expressions. +// Mitigates prototype pollution and constructor escape attacks. +var UNSAFE_PROPERTY_NAMES = Object.create(null); + +/* jshint -W069: true */ +UNSAFE_PROPERTY_NAMES['constructor'] = true; +UNSAFE_PROPERTY_NAMES['__proto__'] = true; +UNSAFE_PROPERTY_NAMES['prototype'] = true; +/* jshint -W069: false */ + +function isUnsafePropertyName(name) { + return typeof name === 'string' && UNSAFE_PROPERTY_NAMES[name] === true; +} + +function isSafeAst(ast) { + if (!ast || typeof ast !== 'object') return false; + + function walk(node) { + if (!node || typeof node !== 'object' || !node.type) { + return false; + } + + switch (node.type) { + + // ===== SAFE TERMINALS ===== + + case 'Literal': + return true; + + case 'Identifier': + // Only allow the special scope identifier + return node.name === '@'; + + + // ===== PROPERTY ACCESS ===== + + case 'MemberExpression': { + if (!walk(node.object)) { + return false; + } + + // Non-computed: obj.property + if (!node.computed && node.property.type === 'Identifier') { + if (isUnsafePropertyName(node.property.name)) { + return false; + } + return true; + } + + // Computed: obj["property"] + if (node.computed) { + if (!walk(node.property)) { + return false; + } + + if ( + node.property.type === 'Literal' && + isUnsafePropertyName(String(node.property.value)) + ) { + return false; + } + + return true; + } + + return false; + } + + + // ===== EXPRESSIONS ===== + + case 'UnaryExpression': + return walk(node.argument); + + case 'BinaryExpression': + case 'LogicalExpression': + return walk(node.left) && walk(node.right); + + case 'ConditionalExpression': + return ( + walk(node.test) && + walk(node.consequent) && + walk(node.alternate) + ); + + case 'ArrayExpression': + for (var i = 0; i < node.elements.length; i++) { + if (!walk(node.elements[i])) { + return false; + } + } + return true; + + case 'ObjectExpression': + for (var j = 0; j < node.properties.length; j++) { + var prop = node.properties[j]; + + // Reject unsafe keys + if ( + prop.key && + ( + (prop.key.type === 'Identifier' && + isUnsafePropertyName(prop.key.name)) || + (prop.key.type === 'Literal' && + isUnsafePropertyName(String(prop.key.value))) + ) + ) { + return false; + } + + if (!walk(prop.value)) { + return false; + } + } + return true; + + + // ===== EXPLICITLY REJECT DANGEROUS TYPES ===== + // Security: do not rely on default deny; list each code-execution / escape vector. + + case 'CallExpression': + case 'NewExpression': + case 'FunctionExpression': + case 'ArrowFunctionExpression': + case 'ThisExpression': + case 'AssignmentExpression': + case 'UpdateExpression': + case 'SequenceExpression': + case 'TemplateLiteral': + case 'TemplateElement': + case 'TaggedTemplateExpression': + case 'ReturnStatement': + case 'ExpressionStatement': + return false; + + + // ===== DEFAULT DENY ===== + + default: + return false; + } + } + + return walk(ast); +} + var Handlers = function() { return this.initialize.apply(this, arguments); } @@ -239,8 +385,11 @@ function _traverse(passable) { } } -function evaluate() { - try { return _evaluate.apply(this, arguments) } +function evaluate(ast, scope) { + if (!isSafeAst(ast)) { + throw new Error('Unsafe expression: script and filter expressions may only access the current node (@) with safe property names'); + } + try { return _evaluate(ast, scope) } catch (e) { } }
test/security.js+187 −0 modified@@ -48,4 +48,191 @@ suite('security', function() { }, /Unsafe key/); assert.equal(({}).polluted, undefined); }); + + suite('CVE-2026-1615: blocks code injection in filter/script expressions', function() { + var data = { a: {}, b: [1, 2, 3] }; + + test('rejects constructor access in filter expression', function() { + assert.throws(function() { + jp.query(data, '$[?(@.constructor)]'); + }, /Unsafe expression/); + }); + + test('rejects constructor.constructor in filter expression', function() { + assert.throws(function() { + jp.query(data, '$[?(@.constructor.constructor)]'); + }, /Unsafe expression/); + }); + + test('rejects chained constructor.constructor call: @.foo["constructor"]["constructor"](...)()', function() { + assert.throws(function() { + jp.query(data, '$[?(@.foo["constructor"]["constructor"]("return process")())]'); + }, /Unsafe expression/); + }); + + test('rejects __proto__ access in filter expression', function() { + assert.throws(function() { + jp.query(data, '$[?(@.__proto__)]'); + }, /Unsafe expression/); + }); + + test('rejects function call in filter expression', function() { + assert.throws(function() { + jp.query(data, '$[?(process.exit(1))]'); + }, /Unsafe expression/); + }); + + test('rejects constructor access in script expression', function() { + var scriptData = { a: [1, 2, 3] }; + assert.throws(function() { + jp.query(scriptData, '$[(@.constructor)]'); + }, /Unsafe expression/); + }); + + test('allows safe filter expressions', function() { + var storeData = { store: { book: [ { price: 5 }, { price: 15 } ] } }; + var results = jp.query(storeData, '$..book[?(@.price<10)]'); + assert.deepEqual(results, [ { price: 5 } ]); + }); + + test('allows safe script expressions', function() { + var bookData = { book: [ { id: 1 }, { id: 2 }, { id: 3 } ] }; + var results = jp.nodes(bookData, '$..book[(@.length-1)]'); + assert.deepEqual(results[0].value, { id: 3 }); + }); + + test('rejects bracket notation constructor: @["constructor"]', function() { + assert.throws(function() { jp.query(data, '$[?(@["constructor"])]'); }, /Unsafe expression/); + }); + + test('rejects bracket notation __proto__: @["__proto__"]', function() { + assert.throws(function() { jp.query(data, '$[?(@["__proto__"])]'); }, /Unsafe expression/); + }); + + test('rejects bracket notation prototype: @["prototype"]', function() { + assert.throws(function() { jp.query(data, '$[?(@["prototype"])]'); }, /Unsafe expression/); + }); + + test('rejects ObjectExpression with unsafe key: { "__proto__": @ }', function() { + assert.throws(function() { jp.query(data, '$[?({ "__proto__": @ })]'); }, /Unsafe expression|Unexpected token/); + }); + + test('rejects ObjectExpression with unsafe key: { "constructor": @ }', function() { + assert.throws(function() { jp.query(data, '$[?({ "constructor": @ })]'); }, /Unsafe expression|Unexpected token/); + }); + + test('rejects ObjectExpression with unsafe key: { "prototype": @ }', function() { + assert.throws(function() { jp.query(data, '$[?({ "prototype": @ })]'); }, /Unsafe expression|Unexpected token/); + }); + + test('rejects unicode escape constructor in bracket: @["\\u0063onstructor"]', function() { + assert.throws(function() { jp.query(data, '$[?(@["\\u0063onstructor"])]'); }, /Unsafe expression/); + }); + + test('rejects unicode escape __proto__ in bracket', function() { + var path = '$[?(@["\\u005f\\u005fproto\\u005f\\u005f"])]'; + assert.throws(function() { jp.query(data, path); }, /Unsafe expression/); + }); + + test('rejects IIFE: (function(){return 1})()', function() { + assert.throws(function() { jp.query(data, '$[?((function(){return 1})())]'); }, /Unsafe expression/); + }); + + test('rejects direct function call: process.exit(1)', function() { + assert.throws(function() { jp.query(data, '$[?(process.exit(1))]'); }, /Unsafe expression/); + }); + + test('rejects require() call', function() { + assert.throws(function() { jp.query(data, '$[?(require("fs"))]'); }, /Unsafe expression/); + }); + + test('rejects eval() call', function() { + assert.throws(function() { jp.query(data, '$[?(eval("1"))]'); }, /Unsafe expression/); + }); + + test('rejects globalThis / global identifier', function() { + assert.throws(function() { jp.query(data, '$[?(globalThis)]'); }, /Unsafe expression/); + assert.throws(function() { jp.query(data, '$[?(global)]'); }, /Unsafe expression/); + }); + + test('rejects NewExpression: new Function("return 1")()', function() { + assert.throws(function() { jp.query(data, '$[?(new Function("return 1")())]'); }, /Unsafe expression/); + }); + + test('rejects JSFuck-style: [] ["filter"]["constructor"]', function() { + assert.throws(function() { jp.query(data, '$[?([]["filter"]["constructor"])]'); }, /Unsafe expression/); + }); + + test('rejects JSFuck-style constructor call (no @)', function() { + assert.throws(function() { jp.query(data, '$[?([]["filter"]["constructor"]("return 1")())]'); }, /Unsafe expression/); + }); + + test('rejects sequence expression: (1, process.exit)(1)', function() { + assert.throws(function() { jp.query(data, '$[?((1, process.exit)(1))]'); }, /Unsafe expression/); + }); + + test('rejects method call on @: @.valueOf()', function() { + assert.throws(function() { jp.query(data, '$[?(@.valueOf())]'); }, /Unsafe expression/); + }); + + test('rejects method call: @.toString()', function() { + assert.throws(function() { jp.query(data, '$[?(@.toString())]'); }, /Unsafe expression/); + }); + + test('rejects template literal in computed: @[`constructor`]', function() { + assert.throws(function() { jp.query(data, '$[?(@[`constructor`])]'); }, /Unsafe expression|Unexpected token|ILLEGAL/); + }); + + test('rejects tagged template (code execution vector)', function() { + assert.throws(function() { jp.query(data, '$[?(String.raw`x`)]'); }, /Unsafe expression|Unexpected token|ILLEGAL/); + }); + + test('rejects ArrowFunctionExpression', function() { + assert.throws(function() { jp.query(data, '$[?((()=>1)())]'); }, /Unsafe expression|Unexpected token/); + }); + + test('rejects ThisExpression (this)', function() { + assert.throws(function() { jp.query(data, '$[?(this)]'); }, /Unsafe expression/); + }); + + test('rejects script expression with constructor', function() { + assert.throws(function() { jp.query(data, '$[(@.constructor)]'); }, /Unsafe expression/); + }); + + test('rejects script expression with call', function() { + assert.throws(function() { jp.query(data, '$[((function(){return 0})())]'); }, /Unsafe expression/); + }); + + test('allows @.length (no call)', function() { + var r = jp.query(data, '$[?(@.length)]'); + assert.ok(Array.isArray(r)); + }); + + test('allows bracket with safe key: @["length"]', function() { + var r = jp.query(data, '$[?(@["length"])]'); + assert.ok(Array.isArray(r)); + }); + + test('allows @["@class"] (existing test pattern)', function() { + var d = { DIV: [{ '@class': 'value', val: 5 }] }; + var r = jp.query(d, '$..DIV[?(@["@class"]=="value")]'); + assert.deepEqual(r, d.DIV); + }); + + test('rejects prototype access in filter', function() { + assert.throws(function() { jp.query(data, '$[?(@.prototype)]'); }, /Unsafe expression/); + }); + + test('rejects comma/sequence that could hide call', function() { + assert.throws(function() { jp.query(data, '$[?((0, eval)("1"))]'); }, /Unsafe expression/); + }); + + test('rejects AssignmentExpression', function() { + assert.throws(function() { jp.query(data, '$[?((x=1)==1)]'); }, /Unsafe expression/); + }); + + test('rejects UpdateExpression (++, --)', function() { + assert.throws(function() { jp.query(data, '$[?(@.x++)]'); }, /Unsafe expression/); + }); + }); });
Vulnerability mechanics
Generated by null/stub on May 9, 2026. Inputs: CWE entries + fix-commit diffs from this CVE's patches. Citations validated against bundle.
References
9- github.com/advisories/GHSA-87r5-mp6g-5w5jghsaADVISORY
- nvd.nist.gov/vuln/detail/CVE-2026-1615ghsaADVISORY
- github.com/dchester/jsonpath/blob/c1dd8ec74034fb0375233abb5fdbec51ac317b4b/lib/handlers.jsghsaWEB
- github.com/dchester/jsonpath/commit/491e2e01de2ff13f7d95e87eb2be726edbf4225fghsaWEB
- github.com/dchester/jsonpath/commit/b61111f07ac1a8d0f3133b5fc51438ecb76a6c39nvdWEB
- github.com/dchester/jsonpath/pull/197ghsaWEB
- security.snyk.io/vuln/SNYK-JAVA-ORGWEBJARSNPM-15141219nvdWEB
- security.snyk.io/vuln/SNYK-JS-JSONPATH-13645034nvdWEB
- github.com/dchester/jsonpath/blob/c1dd8ec74034fb0375233abb5fdbec51ac317b4b/lib/handlers.js%23L243nvd
News mentions
0No linked articles in our index yet.