Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion badges/tests-badge.svg
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
5 changes: 1 addition & 4 deletions dist/index-browser-esm.js
Original file line number Diff line number Diff line change
Expand Up @@ -1310,7 +1310,7 @@ const SafeEval = {
throw TypeError(`Cannot read properties of ${obj} (reading '${prop}')`);
}
const result = obj[prop];
if (typeof result === 'function') {
if (typeof result === 'function' && result !== Function) {
return result.bind(obj); // arrow functions aren't affected by bind.
}
return result;
Expand All @@ -1334,12 +1334,9 @@ const SafeEval = {
evalCallExpression(ast, subs) {
const args = ast.arguments.map(arg => SafeEval.evalAst(arg, subs));
const func = SafeEval.evalAst(ast.callee, subs);
/* c8 ignore start */
if (func === Function) {
// unreachable since BLOCKED_PROTO_PROPERTIES includes 'constructor'
throw new Error('Function constructor is disabled');
}
/* c8 ignore end */
return func(...args);
},
evalAssignmentExpression(ast, subs) {
Expand Down
2 changes: 1 addition & 1 deletion dist/index-browser-esm.min.js

Large diffs are not rendered by default.

2 changes: 1 addition & 1 deletion dist/index-browser-esm.min.js.map

Large diffs are not rendered by default.

5 changes: 1 addition & 4 deletions dist/index-browser-umd.cjs
Original file line number Diff line number Diff line change
Expand Up @@ -1316,7 +1316,7 @@
throw TypeError(`Cannot read properties of ${obj} (reading '${prop}')`);
}
const result = obj[prop];
if (typeof result === 'function') {
if (typeof result === 'function' && result !== Function) {
return result.bind(obj); // arrow functions aren't affected by bind.
}
return result;
Expand All @@ -1340,12 +1340,9 @@
evalCallExpression(ast, subs) {
const args = ast.arguments.map(arg => SafeEval.evalAst(arg, subs));
const func = SafeEval.evalAst(ast.callee, subs);
/* c8 ignore start */
if (func === Function) {
// unreachable since BLOCKED_PROTO_PROPERTIES includes 'constructor'
throw new Error('Function constructor is disabled');
}
/* c8 ignore end */
return func(...args);
},
evalAssignmentExpression(ast, subs) {
Expand Down
2 changes: 1 addition & 1 deletion dist/index-browser-umd.min.cjs

Large diffs are not rendered by default.

2 changes: 1 addition & 1 deletion dist/index-browser-umd.min.cjs.map

Large diffs are not rendered by default.

5 changes: 1 addition & 4 deletions dist/index-node-cjs.cjs
Original file line number Diff line number Diff line change
Expand Up @@ -1314,7 +1314,7 @@ const SafeEval = {
throw TypeError(`Cannot read properties of ${obj} (reading '${prop}')`);
}
const result = obj[prop];
if (typeof result === 'function') {
if (typeof result === 'function' && result !== Function) {
return result.bind(obj); // arrow functions aren't affected by bind.
}
return result;
Expand All @@ -1338,12 +1338,9 @@ const SafeEval = {
evalCallExpression(ast, subs) {
const args = ast.arguments.map(arg => SafeEval.evalAst(arg, subs));
const func = SafeEval.evalAst(ast.callee, subs);
/* c8 ignore start */
if (func === Function) {
// unreachable since BLOCKED_PROTO_PROPERTIES includes 'constructor'
throw new Error('Function constructor is disabled');
}
/* c8 ignore end */
return func(...args);
},
evalAssignmentExpression(ast, subs) {
Expand Down
5 changes: 1 addition & 4 deletions dist/index-node-esm.js
Original file line number Diff line number Diff line change
Expand Up @@ -1312,7 +1312,7 @@ const SafeEval = {
throw TypeError(`Cannot read properties of ${obj} (reading '${prop}')`);
}
const result = obj[prop];
if (typeof result === 'function') {
if (typeof result === 'function' && result !== Function) {
return result.bind(obj); // arrow functions aren't affected by bind.
}
return result;
Expand All @@ -1336,12 +1336,9 @@ const SafeEval = {
evalCallExpression(ast, subs) {
const args = ast.arguments.map(arg => SafeEval.evalAst(arg, subs));
const func = SafeEval.evalAst(ast.callee, subs);
/* c8 ignore start */
if (func === Function) {
// unreachable since BLOCKED_PROTO_PROPERTIES includes 'constructor'
throw new Error('Function constructor is disabled');
}
/* c8 ignore end */
return func(...args);
},
evalAssignmentExpression(ast, subs) {
Expand Down
5 changes: 1 addition & 4 deletions src/Safe-Script.js
Original file line number Diff line number Diff line change
Expand Up @@ -138,7 +138,7 @@ const SafeEval = {
);
}
const result = obj[prop];
if (typeof result === 'function') {
if (typeof result === 'function' && result !== Function) {
return result.bind(obj); // arrow functions aren't affected by bind.
}
return result;
Expand All @@ -162,12 +162,9 @@ const SafeEval = {
evalCallExpression (ast, subs) {
const args = ast.arguments.map((arg) => SafeEval.evalAst(arg, subs));
const func = SafeEval.evalAst(ast.callee, subs);
/* c8 ignore start */
if (func === Function) {
// unreachable since BLOCKED_PROTO_PROPERTIES includes 'constructor'
throw new Error('Function constructor is disabled');
}
/* c8 ignore end */
return func(...args);
},
evalAssignmentExpression (ast, subs) {
Expand Down
9 changes: 9 additions & 0 deletions test/test.safe-eval.js
Original file line number Diff line number Diff line change
Expand Up @@ -300,6 +300,15 @@ checkBuiltInVMAndNodeVM(function (vmType, setBuiltInState) {
jsonpath({json: exampleObj, path: userControlledPath});
}, "Cannot read properties of (reading 'constructor')");
});
it("10.4.1 RCE", () => {
assert.throws(() => {
globalThis.TEST_10_4_1_RCE = 'not exploited';

const path = "$..[?(@.constructor[( @.getPrototypeOf(@).constructor('globalThis.TEST_10_4_1_RCE=\"RCE\";0')() )])]";

jsonpath({path, json: {a: {}}});
}, "Function constructor is disabled");
});
});
});
});