diff --git a/packages/shell-bson-parser/src/check.ts b/packages/shell-bson-parser/src/check.ts index 26fb2c18..3bf149fa 100644 --- a/packages/shell-bson-parser/src/check.ts +++ b/packages/shell-bson-parser/src/check.ts @@ -23,7 +23,16 @@ class Checker { const object = node.callee.object; const property = node.callee.property as Identifier; // If we're only referring to identifiers, we don't need to check deeply. - if (object.type === 'Identifier' && property.type === 'Identifier') { + + if (object.type === 'Literal' && property.type === 'Identifier') { + return ( + isMethodWhitelisted(typeof object.value, property.name) && + node.arguments.every(this.checkSafeExpression) + ); + } else if ( + object.type === 'Identifier' && + property.type === 'Identifier' + ) { return ( isMethodWhitelisted(object.name, property.name) && node.arguments.every(this.checkSafeExpression) diff --git a/packages/shell-bson-parser/src/index.spec.ts b/packages/shell-bson-parser/src/index.spec.ts index 88899ec5..20da8f1a 100644 --- a/packages/shell-bson-parser/src/index.spec.ts +++ b/packages/shell-bson-parser/src/index.spec.ts @@ -724,6 +724,23 @@ describe('@mongodb-js/shell-bson-parser', function () { }); }); } + + it('should not allow calling IIFE', function () { + expect( + parse('{ date: (function() { return "10"; })() }', options), + ).to.equal(''); + }); + + it('should prevent attempting to break the sandbox for identifiers', function () { + const input = + "{ exploit: clearImmediate.constructor('return process;')().exit(1) }"; + expect(parse(input, options)).to.equal(''); + }); + + it('should prevent attempting to break the sandbox for literals', function () { + const input = `{ exploit: "".toString.constructor('return process;')().exit(1) }`; + expect(parse(input, options)).to.equal(''); + }); }); describe('Comments', function () { @@ -751,16 +768,6 @@ describe('@mongodb-js/shell-bson-parser', function () { }); }); - it('should not allow calling IIFE', function () { - expect(parse('{ date: (function() { return "10"; })() }')).to.equal(''); - }); - - it('should prevent attempting to break the sandbox', function () { - const input = - "{ exploit: clearImmediate.constructor('return process;')().exit(1) }"; - expect(parse(input)).to.equal(''); - }); - it('should correctly parse NumberLong and Int64 bigger than Number.MAX_SAFE_INTEGER', function () { expect( parse("{ n: NumberLong('345678654321234552') }").n.toString(),