diff --git a/src/core/operations/JPathExpression.mjs b/src/core/operations/JPathExpression.mjs index 328fc83f..7e1b9c3d 100644 --- a/src/core/operations/JPathExpression.mjs +++ b/src/core/operations/JPathExpression.mjs @@ -49,6 +49,14 @@ class JPathExpression extends Operation { let results, obj; + // Split the string by literal quotes + const quoteSplit = query.split(/(?<=[^\\])"/); + for (let i = 0; i < quoteSplit.length; i++) { + // Only check the text that isn't surrounded by quotes. + if (i % 2 === 0 && quoteSplit[i].match(/\[\??\(/)) + throw new OperationError("Query contains unsafe expression."); + } + try { obj = JSON.parse(input); } catch (err) { diff --git a/tests/operations/tests/Code.mjs b/tests/operations/tests/Code.mjs index 94179553..06cf03ff 100644 --- a/tests/operations/tests/Code.mjs +++ b/tests/operations/tests/Code.mjs @@ -310,6 +310,17 @@ TestRegister.addTests([ } ], }, + { + name: "JPath Expression: Script-based expression", + input: "[{}]", + recipeConfig: [ + { + "op": "JPath expression", + "args": ["$..[?(({__proto__:[].constructor}).constructor(\"self.postMessage({action:'bakeComplete',data:{bakeId:1,dish:{type:1,value:''},duration:1,error:false,id:undefined,inputNum:2,progress:1,result:'