diff --git a/src/common.js b/src/common.js index 30d665c..998e2ba 100644 --- a/src/common.js +++ b/src/common.js @@ -47,13 +47,17 @@ exports.createContext = function () { cloneFunctions(context) context.Buffer = _protect('Buffer') context.console = clones(console, console) // console needs special treatment + context.console.constructor.constructor = 'function () {}' } if (hasWindow) { fillContext(window, true) cloneFunctions(context) protectBuiltInObjects(context) context.console = clones(console, console) // console needs special treatment - context.Object.constructor.constructor = 'function () {}' + try { + context.Object.constructor.constructor = 'function () {}' + } catch (e) { + } } return context @@ -82,7 +86,7 @@ function cloneFunctions (context) { 'clearTimeout' ].forEach((str) => { try { - let fn = new Function(`return ${str}`)() // eslint-disable-line no-new-func + const fn = new Function(`return ${str}`)() // eslint-disable-line no-new-func context[str] = fn ? function () { return fn.apply(null, [].slice.call(arguments)) @@ -97,7 +101,7 @@ function cloneFunctions (context) { 'setTimeout' ].forEach((str) => { try { - let fn = new Function(`return ${str}`)() // eslint-disable-line no-new-func + const fn = new Function(`return ${str}`)() // eslint-disable-line no-new-func context[str] = fn ? function (f) { if (typeof f === 'function') { @@ -175,7 +179,7 @@ function protectBuiltInObjects (context) { */ function _protect (str) { try { - let type = new Function(`return ${str}`)() // eslint-disable-line no-new-func + const type = new Function(`return ${str}`)() // eslint-disable-line no-new-func return type ? clones.classes(type) : undefined diff --git a/test/saferEval.spec.js b/test/saferEval.spec.js index 1dae58c..22ebd8a 100644 --- a/test/saferEval.spec.js +++ b/test/saferEval.spec.js @@ -83,8 +83,9 @@ describe('#saferEval', function () { }) it('setInterval passing a function', function (done) { - var res = saferEval('(function (){var id = setInterval(function () {Array._test = 111; console.log("intervall"); clearInterval(id)}, 5)}())') - assert.strictEqual(res) + var res = saferEval('(function (){var id = setInterval(function () {Array._test = 111; console.log("interval"); clearInterval(id)}, 5)})') + assert.strictEqual(typeof res, 'function') + res() setTimeout(function () { assert.strictEqual(Array._test, undefined) done() @@ -270,6 +271,22 @@ describe('#saferEval', function () { } assert.strictEqual(res, undefined) }) + it('should not allow using console.constructor.constructor', function () { + let res + try { + res = saferEval("console.constructor.constructor('return process')().env") + } catch (e) { + } + assert.strictEqual(res, undefined) + }) + it('should not allow using JSON.constructor.constructor', function () { + let res + try { + res = saferEval("JSON.constructor.constructor('return process')().env") + } catch (e) { + } + assert.strictEqual(res, undefined) + }) it('should prevent a breakout using Object.constructor', function () { let res try { @@ -301,7 +318,15 @@ describe('#saferEval', function () { it('should not allow using Object.constructor.constructor', function () { let res try { - res = saferEval("Object.constructor.constructor('return localStorage')()") + res = saferEval("Object.constructor.constructor('return window')()") + } catch (e) { + } + assert.strictEqual(res, undefined) + }) + it('should not allow using console.constructor.constructor', function () { + let res + try { + res = saferEval("console.constructor.constructor('return window')()") } catch (e) { } assert.strictEqual(res, undefined) diff --git a/webpack.config.js b/webpack.config.js index 188155e..f7bee3c 100644 --- a/webpack.config.js +++ b/webpack.config.js @@ -6,8 +6,8 @@ module.exports = { devtool: 'source-map', resolve: { alias: { - 'src': path.resolve(__dirname, 'src'), - 'lib': path.resolve(__dirname, 'lib') + src: path.resolve(__dirname, 'src'), + lib: path.resolve(__dirname, 'lib') } }, module: {