flow like the river

This commit is contained in:
root 2025-11-07 00:06:12 +01:00
commit 013fe673f3
42435 changed files with 5764238 additions and 0 deletions

20
VISUALIZACION/node_modules/safer-eval/LICENSE generated vendored Executable file
View file

@ -0,0 +1,20 @@
The MIT License (MIT)
Copyright (c) 2017- commenthol
Permission is hereby granted, free of charge, to any person obtaining a copy of
this software and associated documentation files (the "Software"), to deal in
the Software without restriction, including without limitation the rights to
use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of
the Software, and to permit persons to whom the Software is furnished to do so,
subject to the following conditions:
The above copyright notice and this permission notice shall be included in all
copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS
FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR
COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.

166
VISUALIZACION/node_modules/safer-eval/README.md generated vendored Executable file
View file

@ -0,0 +1,166 @@
# safer-eval but harmful
[![NPM version](https://badge.fury.io/js/safer-eval.svg)](https://www.npmjs.com/package/safer-eval/)
> harmful as eval
This approach has proven to be HARMFUL and does not suit as repacement for eval in node and browser.
Before using this module, **ask yourself if there are no better options** than using saferEval.
It is potentially better than the bad old `eval()` but has harmful potential.
Checkout the "harmful context" tests section.
![harmful](https://raw.githubusercontent.com/commenthol/safer-eval/master/harmful.png)
**Warning:** The `saferEval` function is harmful - so you are warned!
Better packages:
- For node check [vm2](https://www.npmjs.com/package/vm2).
----
If you like to **post exploits** you found on this module, feel free to do so.
Please file an issue with your findings.
Maybe this helps then others to build a better sandbox.
----
In node the `vm` module is used to sandbox the evaluation of `code`.
The browser version `browser.js` might not be as safe as the node version
`index.js` as here no real sandboxing is available. Please consider modules like
[sandboxr](https://www.npmjs.com/package/sandboxr).
Runs on node and in modern browsers:
| | Versions |
| --- | --- |
| **node** | 8, 10, 11, 12 |
| **Chrome** | 70, 75 |
| **Firefox** | 60, 68 |
| **Edge** | 17, 18 |
| **IE** | ~~11~~ |
| **Safari** | 11, 12|
| **iOS Safari** | 11.3, 12.0 |
## Installation
```
npm install --save safer-eval
```
## Implementation recommendations
**Use strict mode**
Always use `'use strict'` mode in functions/ files calling `saferEval()`.
Otherwise a sandbox breakout may be possible.
```js
'use strict'
const saferEval = require('safer-eval')
function main () {
'use strict' //< alternative within function
const res = saferEval('new Date()')
...
}
```
**Run in worker**
Be aware that a
```js
saferEval('(function () { while (true) {} })()')
```
may run
infinitely. Consider using the module from within a worker thread which is terminated
after timeout.
**Avoid context props**
Avoid passing `context` props while deserializing data from hostile environments.
## Usage
`context` allows the definition of passed in Objects into the sandbox.
Take care, injected `code` can overwrite those passed context props!
Check the tests under "harmful context"!
**Parameters**
**code**: `String`, a string containing javascript code
**context**: `Object`, define globals, properties for evaluation context
**Returns**: `Any`, evaluated code
**Example**:
in node:
```js
'use strict' //< NEVER FORGET TO ADD STRICT MODE in file/ function
//< running `saferEval`
const saferEval = require('safer-eval')
const code = `{d: new Date('1970-01-01'), b: new Buffer('data')}`
const res = saferEval(code)
// => toString.call(res.d) = '[object Date]'
// => toString.call(res.b) = '[object Buffer]'
```
in browser:
```js
'use strict' //< NEVER FORGET TO ADD STRICT MODE in file/ function
//< running `saferEval`
const saferEval = require('safer-eval')
const code = `{d: new Date('1970-01-01'), b: function () { return navigator.userAgent }`
const res = saferEval(code, {navigator: window.navigator})
// => toString.call(res.d) = '[object Date]'
// => toString.call(res.b) = '[object Function]'
// => res.b() = "Mozilla/5.0 (..."
```
To minimize any harmful code injection carefully select the methods you allow in `context`
```js
const code = `window.btoa('Hello, world')`
// AVOID passing a GLOBAL context!!!
const res = saferEval(code, {window: window})
// BETTER - code needs only access to window.btoa
const clones = require('clones')
const context = {
window: {
btoa: clones(window.btoa, window)
}
}
const res = saferEval(code ,context)
// => res = 'SGVsbG8sIHdvcmxk'
```
## Reusing context
Use `new SaferEval()` to reuse a once created context.
```js
'use strict' //< NEVER FORGET TO ADD STRICT MODE in file/ function
//< running `saferEval`
const { SaferEval } = require('safer-eval')
const safer = new SaferEval()
const code = `{d: new Date('1970-01-01'), b: new Buffer('data')}`
const res = safer.runInContext(code)
```
## License
[MIT](./LICENSE)
[clones]: https://github.com/commenthol/clones

BIN
VISUALIZACION/node_modules/safer-eval/harmful.png generated vendored Executable file

Binary file not shown.

After

Width:  |  Height:  |  Size: 27 KiB

102
VISUALIZACION/node_modules/safer-eval/lib/browser.js generated vendored Executable file
View file

@ -0,0 +1,102 @@
/**
* @copyright 2017 Commenthol
* @license MIT
*/
'use strict';
function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError("Cannot call a class as a function"); } }
function _defineProperties(target, props) { for (var i = 0; i < props.length; i++) { var descriptor = props[i]; descriptor.enumerable = descriptor.enumerable || false; descriptor.configurable = true; if ("value" in descriptor) descriptor.writable = true; Object.defineProperty(target, descriptor.key, descriptor); } }
function _createClass(Constructor, protoProps, staticProps) { if (protoProps) _defineProperties(Constructor.prototype, protoProps); if (staticProps) _defineProperties(Constructor, staticProps); return Constructor; }
var _require = require('./common'),
createContext = _require.createContext,
allow = _require.allow;
/**
* reuse saferEval context
* @class
* @example
* const {SaferEval} = require('safer-eval')
* const safer = new SaferEval()
* let res1 = safer.runInContext('new Date('1970-01-01')')
* let res2 = safer.runInContext('new Date('1970-07-01')')
*/
var SaferEval =
/*#__PURE__*/
function () {
/**
* @param {Object} [context] - allowed context
*/
function SaferEval(context) {
_classCallCheck(this, SaferEval);
// define disallowed objects in context
var __context = createContext(); // apply "allowed" context vars
allow(context, __context);
this._context = __context;
}
/**
* @param {String} code - a string containing javascript code
* @return {Any} evaluated code
*/
_createClass(SaferEval, [{
key: "runInContext",
value: function runInContext(code) {
if (typeof code !== 'string') {
throw new TypeError('not a string');
}
var __context = this._context;
var src = 'this.constructor.constructor = function () {};\n'; // set local scope vars from each context property
Object.keys(__context).forEach(function (key) {
src += 'var ' + key + ' = __context[\'' + key + '\'];\n';
});
src += 'return ' + code + ';\n';
return Function('__context', src).call(null, __context); // eslint-disable-line
}
}]);
return SaferEval;
}();
/**
* A safer approach for eval. (Browser)
*
* This might not be as safe as the nodeJs version as there is no real sandboxing
* available in the browser.
*
* **Warning: This function might be harmful - so you are warned!**
*
* `context` allows the definition of passed in Objects into the sandbox.
* Take care, injected `code` can overwrite those passed context props!
* Check the tests under "harmful context"!
*
* @static
* @throws Error
* @param {String} code - a string containing javascript code
* @param {Object} [context] - define globals, properties for evaluation context
* @param {Object} [opts] - options
* @param {Object} [opts.freeze=true] - freeze all native objects
* @return {Any} evaluated code
* @example
* var code = `{d: new Date('1970-01-01'), b: function () { return navigator.userAgent }`
* var res = saferEval(code, {navigator: window.navigator})
* // => toString.call(res.d) = '[object Date]'
* // => toString.call(res.b) = '[object Function]'
*/
function saferEval(code, context) {
var opts = arguments.length > 2 && arguments[2] !== undefined ? arguments[2] : {};
return new SaferEval(context).runInContext(code);
}
module.exports = saferEval;
module.exports.SaferEval = SaferEval;

140
VISUALIZACION/node_modules/safer-eval/lib/common.js generated vendored Executable file
View file

@ -0,0 +1,140 @@
'use strict';
var clones = require('clones');
var hasWindow = typeof window !== 'undefined';
exports.hasWindow = hasWindow;
var hasGlobal = typeof global !== 'undefined';
exports.hasGlobal = hasGlobal;
var FN_NOOP = 'function () {}';
var NON_IDENTIFIER = /^\d|-|^(break|case|catch|continue|debugger|default|delete|do|else|finally|for|function|if|in|instanceof|new|return|switch|this|throw|try|typeof|var|void|while|with|class|const|enum|export|extends|import|super|implements|interface|let|package|private|protected|public|static|yield|null|true|false)$/;
var isIdentifier = function isIdentifier(key) {
return !NON_IDENTIFIER.test(key);
};
exports.isIdentifier = isIdentifier;
/**
* create a fresh context where nearly nothing is allowed
* @private
*/
exports.createContext = function () {
// protection might not be complete!
var context = {
// disallowed
global: undefined,
process: undefined,
module: undefined,
require: undefined,
document: undefined,
window: undefined,
Window: undefined,
// no evil...
eval: undefined,
Function: undefined
};
var fillContext = function fillContext(root) {
Object.keys(root).forEach(function (key) {
if (isIdentifier(key)) {
context[key] = undefined;
}
});
}; // locally define all potential global vars
if (hasGlobal) {
fillContext(global);
cloneFunctions(context);
context.Buffer = _protect('Buffer');
context.console = clones(console, console); // console needs special treatment
context.console.constructor.constructor = FN_NOOP;
}
if (hasWindow) {
fillContext(window, true);
cloneFunctions(context);
protectBuiltInObjects(context);
context.console = clones(console, console); // console needs special treatment
try {
context.Object.constructor.constructor = FN_NOOP;
} catch (e) {}
}
return context;
};
/**
* Apply allowed context properties
* @private
*/
exports.allow = function (context, newContext) {
Object.keys(context || {}).forEach(function (key) {
if (isIdentifier(key)) {
newContext[key] = context[key]; // this is harmful - objects can be overwritten
}
});
};
/**
* clone global functions
* @private
*/
function cloneFunctions(context) {
;
['clearImmediate', 'clearInterval', 'clearTimeout'].forEach(function (str) {
try {
var fn = new Function("return ".concat(str))(); // eslint-disable-line no-new-func
context[str] = fn ? function () {
return fn.apply(null, [].slice.call(arguments));
} : undefined;
} catch (e) {}
});
['setImmediate', 'setInterval', 'setTimeout'].forEach(function (str) {
try {
var fn = new Function("return ".concat(str))(); // eslint-disable-line no-new-func
context[str] = fn ? function (f) {
if (typeof f === 'function') {
return fn.apply(null, [].slice.call(arguments));
} else {
throw new Error(str + ' requires function as argument');
}
} : undefined;
} catch (e) {}
});
}
/**
* wraps up build-in objects using a cloned copy
* protect object against overwriting
* @private
*/
function protectBuiltInObjects(context) {
;
['Object', 'Boolean', 'Symbol', 'Error', 'EvalError', 'InternalError', 'RangeError', 'ReferenceError', 'SyntaxError', 'TypeError', 'URIError', 'Number', 'Math', 'Date', 'String', 'RegExp', 'Array', 'Int8Array', 'Uint8Array', 'Uint8ClampedArray', 'Int16Array', 'Uint16Array', 'Int32Array', 'Uint32Array', 'Float32Array', 'Float64Array', 'Map', 'Set', 'WeakMap', 'WeakSet', 'ArrayBuffer', 'SharedArrayBuffer', 'Atomics', 'DataView', 'JSON', 'Promise', 'Generator', 'GeneratorFunction', 'Reflect', 'Proxy', 'Intl', 'Buffer'].forEach(function (str) {
try {
context[str] = _protect(str);
new context[str](); // eslint-disable-line no-new
} catch (e) {}
});
}
/**
* @private
*/
function _protect(str) {
try {
var type = new Function("return ".concat(str))(); // eslint-disable-line no-new-func
return type ? clones.classes(type) : undefined;
} catch (e) {}
}

99
VISUALIZACION/node_modules/safer-eval/lib/index.js generated vendored Executable file
View file

@ -0,0 +1,99 @@
/**
* @copyright 2017 Commenthol
* @license MIT
*/
'use strict';
function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError("Cannot call a class as a function"); } }
function _defineProperties(target, props) { for (var i = 0; i < props.length; i++) { var descriptor = props[i]; descriptor.enumerable = descriptor.enumerable || false; descriptor.configurable = true; if ("value" in descriptor) descriptor.writable = true; Object.defineProperty(target, descriptor.key, descriptor); } }
function _createClass(Constructor, protoProps, staticProps) { if (protoProps) _defineProperties(Constructor.prototype, protoProps); if (staticProps) _defineProperties(Constructor, staticProps); return Constructor; }
var vm = require('vm');
var _require = require('./common'),
createContext = _require.createContext,
allow = _require.allow;
/**
* reuse saferEval context
* @class
* @example
* const {SaferEval} = require('safer-eval')
* const safer = new SaferEval()
* let res1 = safer.runInContext('new Date('1970-01-01')')
* let res2 = safer.runInContext('new Date('1970-07-01')')
*/
var SaferEval =
/*#__PURE__*/
function () {
/**
* @param {Object} [context] - allowed context
* @param {Object} [options] - options for `vm.runInContext`
*/
function SaferEval(context, options) {
_classCallCheck(this, SaferEval);
// define disallowed objects in context
var __context = createContext(); // apply "allowed" context vars
allow(context, __context);
this._context = vm.createContext(__context);
this._options = options;
}
/**
* @param {String} code - a string containing javascript code
* @return {Any} evaluated code
*/
_createClass(SaferEval, [{
key: "runInContext",
value: function runInContext(code) {
if (typeof code !== 'string') {
throw new TypeError('not a string');
}
var src = '(function () {"use strict";\n';
src += 'Object.constructor = function () {};\n';
src += 'return ' + code + ';\n';
src += '})()';
return vm.runInContext(src, this._context, this._options);
}
}]);
return SaferEval;
}();
/**
* A safer approach for eval. (node)
*
* In node the `vm` module is used to sandbox the evaluation of `code`.
*
* `context` allows the definition of passed in Objects into the sandbox.
* Take care, injected `code` can overwrite those passed context props!
* Check the tests under "harmful context"!
*
* @static
* @throws Error
* @param {String} code - a string containing javascript code
* @param {Object} [context] - define globals, properties for evaluation context
* @return {Any} evaluated code
* @example
* var code = `{d: new Date('1970-01-01'), b: new Buffer('data')}`
* var res = saferEval(code, {Buffer: Buffer})
* // => toString.call(res.d) = '[object Date]'
* // => toString.call(res.b) = '[object Buffer]'
*/
function saferEval(code, context) {
'use strict';
return new SaferEval(context).runInContext(code);
}
module.exports = saferEval;
module.exports.SaferEval = SaferEval;

72
VISUALIZACION/node_modules/safer-eval/package.json generated vendored Executable file
View file

@ -0,0 +1,72 @@
{
"name": "safer-eval",
"version": "1.3.6",
"description": "harmful as eval",
"keywords": [
"eval",
"safe"
],
"bugs": {
"url": "https://github.com/commenthol/safer-eval/issues"
},
"repository": {
"type": "git",
"url": "https://github.com/commenthol/safer-eval.git"
},
"license": "MIT",
"author": "commenthol <commenthol@gmail.com>",
"main": "./lib/index.js",
"browser": {
"./lib/index.js": "./lib/browser.js"
},
"directories": {
"test": "test"
},
"scripts": {
"preall": "npm run clean",
"all": "npm test",
"clean": "rimraf lib",
"coverage": "nyc -r html -r text npm test",
"prekarma": "npm run transpile",
"karma": "karma start",
"lint": "eslint --fix src test *.js",
"prepublishOnly": "npm run all",
"pretest": "npm run transpile",
"test": "mocha",
"posttest": "npm run lint",
"transpile": "babel -d lib src",
"zuul": "zuul --no-coverage --local 3000 -- test/*.js"
},
"dependencies": {
"clones": "^1.2.0"
},
"devDependencies": {
"@babel/cli": "^7.5.0",
"@babel/core": "^7.5.4",
"@babel/preset-env": "^7.5.4",
"babel-loader": "^8.0.6",
"eslint": "^6.0.1",
"eslint-config-standard": "^13.0.1",
"eslint-plugin-import": "^2.18.0",
"eslint-plugin-node": "^9.1.0",
"eslint-plugin-promise": "^4.2.1",
"eslint-plugin-standard": "^4.0.0",
"karma": "^4.2.0",
"karma-chrome-launcher": "^3.0.0",
"karma-firefox-launcher": "^1.1.0",
"karma-mocha": "^1.3.0",
"karma-sourcemap-loader": "^0.3.7",
"karma-spec-reporter": "~0.0.32",
"karma-webpack": "^4.0.2",
"mocha": "^6.1.4",
"nyc": "^14.1.1",
"rimraf": "^2.6.3",
"webpack": "^4.35.3"
},
"engines": {
"node": ">=6.0.0"
},
"optionalDevDependencies": {
"zuul": "^3.11.1"
}
}

83
VISUALIZACION/node_modules/safer-eval/src/browser.js generated vendored Executable file
View file

@ -0,0 +1,83 @@
/**
* @copyright 2017 Commenthol
* @license MIT
*/
'use strict'
const { createContext, allow } = require('./common')
/**
* reuse saferEval context
* @class
* @example
* const {SaferEval} = require('safer-eval')
* const safer = new SaferEval()
* let res1 = safer.runInContext('new Date('1970-01-01')')
* let res2 = safer.runInContext('new Date('1970-07-01')')
*/
class SaferEval {
/**
* @param {Object} [context] - allowed context
*/
constructor (context) {
// define disallowed objects in context
const __context = createContext()
// apply "allowed" context vars
allow(context, __context)
this._context = __context
}
/**
* @param {String} code - a string containing javascript code
* @return {Any} evaluated code
*/
runInContext (code) {
if (typeof code !== 'string') {
throw new TypeError('not a string')
}
const __context = this._context
let src = 'this.constructor.constructor = function () {};\n'
// set local scope vars from each context property
Object.keys(__context).forEach(function (key) {
src += 'var ' + key + ' = __context[\'' + key + '\'];\n'
})
src += 'return ' + code + ';\n'
return Function('__context', src).call(null, __context) // eslint-disable-line
}
}
/**
* A safer approach for eval. (Browser)
*
* This might not be as safe as the nodeJs version as there is no real sandboxing
* available in the browser.
*
* **Warning: This function might be harmful - so you are warned!**
*
* `context` allows the definition of passed in Objects into the sandbox.
* Take care, injected `code` can overwrite those passed context props!
* Check the tests under "harmful context"!
*
* @static
* @throws Error
* @param {String} code - a string containing javascript code
* @param {Object} [context] - define globals, properties for evaluation context
* @param {Object} [opts] - options
* @param {Object} [opts.freeze=true] - freeze all native objects
* @return {Any} evaluated code
* @example
* var code = `{d: new Date('1970-01-01'), b: function () { return navigator.userAgent }`
* var res = saferEval(code, {navigator: window.navigator})
* // => toString.call(res.d) = '[object Date]'
* // => toString.call(res.b) = '[object Function]'
*/
function saferEval (code, context, opts = {}) {
return new SaferEval(context).runInContext(code)
}
module.exports = saferEval
module.exports.SaferEval = SaferEval

188
VISUALIZACION/node_modules/safer-eval/src/common.js generated vendored Executable file
View file

@ -0,0 +1,188 @@
'use strict'
const clones = require('clones')
const hasWindow = (typeof window !== 'undefined')
exports.hasWindow = hasWindow
const hasGlobal = (typeof global !== 'undefined')
exports.hasGlobal = hasGlobal
const FN_NOOP = 'function () {}'
const NON_IDENTIFIER = /^\d|-|^(break|case|catch|continue|debugger|default|delete|do|else|finally|for|function|if|in|instanceof|new|return|switch|this|throw|try|typeof|var|void|while|with|class|const|enum|export|extends|import|super|implements|interface|let|package|private|protected|public|static|yield|null|true|false)$/
const isIdentifier = key => !NON_IDENTIFIER.test(key)
exports.isIdentifier = isIdentifier
/**
* create a fresh context where nearly nothing is allowed
* @private
*/
exports.createContext = function () {
// protection might not be complete!
const context = {
// disallowed
global: undefined,
process: undefined,
module: undefined,
require: undefined,
document: undefined,
window: undefined,
Window: undefined,
// no evil...
eval: undefined,
Function: undefined
}
const fillContext = (root) => {
Object.keys(root).forEach(key => {
if (isIdentifier(key)) {
context[key] = undefined
}
})
}
// locally define all potential global vars
if (hasGlobal) {
fillContext(global)
cloneFunctions(context)
context.Buffer = _protect('Buffer')
context.console = clones(console, console) // console needs special treatment
context.console.constructor.constructor = FN_NOOP
}
if (hasWindow) {
fillContext(window, true)
cloneFunctions(context)
protectBuiltInObjects(context)
context.console = clones(console, console) // console needs special treatment
try {
context.Object.constructor.constructor = FN_NOOP
} catch (e) {
}
}
return context
}
/**
* Apply allowed context properties
* @private
*/
exports.allow = function (context, newContext) {
Object.keys(context || {}).forEach(key => {
if (isIdentifier(key)) {
newContext[key] = context[key] // this is harmful - objects can be overwritten
}
})
}
/**
* clone global functions
* @private
*/
function cloneFunctions (context) {
;[
'clearImmediate',
'clearInterval',
'clearTimeout'
].forEach((str) => {
try {
const fn = new Function(`return ${str}`)() // eslint-disable-line no-new-func
context[str] = fn
? function () {
return fn.apply(null, [].slice.call(arguments))
}
: undefined
} catch (e) {}
})
;[
'setImmediate',
'setInterval',
'setTimeout'
].forEach((str) => {
try {
const fn = new Function(`return ${str}`)() // eslint-disable-line no-new-func
context[str] = fn
? function (f) {
if (typeof f === 'function') {
return fn.apply(null, [].slice.call(arguments))
} else {
throw new Error(str + ' requires function as argument')
}
}
: undefined
} catch (e) {}
})
}
/**
* wraps up build-in objects using a cloned copy
* protect object against overwriting
* @private
*/
function protectBuiltInObjects (context) {
;[
'Object',
'Boolean',
'Symbol',
'Error',
'EvalError',
'InternalError',
'RangeError',
'ReferenceError',
'SyntaxError',
'TypeError',
'URIError',
'Number',
'Math',
'Date',
'String',
'RegExp',
'Array',
'Int8Array',
'Uint8Array',
'Uint8ClampedArray',
'Int16Array',
'Uint16Array',
'Int32Array',
'Uint32Array',
'Float32Array',
'Float64Array',
'Map',
'Set',
'WeakMap',
'WeakSet',
'ArrayBuffer',
'SharedArrayBuffer',
'Atomics',
'DataView',
'JSON',
'Promise',
'Generator',
'GeneratorFunction',
'Reflect',
'Proxy',
'Intl',
'Buffer'
].forEach((str) => {
try {
context[str] = _protect(str)
new context[str]() // eslint-disable-line no-new
} catch (e) {
}
})
}
/**
* @private
*/
function _protect (str) {
try {
const type = new Function(`return ${str}`)() // eslint-disable-line no-new-func
return type
? clones.classes(type)
: undefined
} catch (e) {}
}

78
VISUALIZACION/node_modules/safer-eval/src/index.js generated vendored Executable file
View file

@ -0,0 +1,78 @@
/**
* @copyright 2017 Commenthol
* @license MIT
*/
'use strict'
const vm = require('vm')
const { createContext, allow } = require('./common')
/**
* reuse saferEval context
* @class
* @example
* const {SaferEval} = require('safer-eval')
* const safer = new SaferEval()
* let res1 = safer.runInContext('new Date('1970-01-01')')
* let res2 = safer.runInContext('new Date('1970-07-01')')
*/
class SaferEval {
/**
* @param {Object} [context] - allowed context
* @param {Object} [options] - options for `vm.runInContext`
*/
constructor (context, options) {
// define disallowed objects in context
const __context = createContext()
// apply "allowed" context vars
allow(context, __context)
this._context = vm.createContext(__context)
this._options = options
}
/**
* @param {String} code - a string containing javascript code
* @return {Any} evaluated code
*/
runInContext (code) {
if (typeof code !== 'string') {
throw new TypeError('not a string')
}
let src = '(function () {"use strict";\n'
src += 'Object.constructor = function () {};\n'
src += 'return ' + code + ';\n'
src += '})()'
return vm.runInContext(src, this._context, this._options)
}
}
/**
* A safer approach for eval. (node)
*
* In node the `vm` module is used to sandbox the evaluation of `code`.
*
* `context` allows the definition of passed in Objects into the sandbox.
* Take care, injected `code` can overwrite those passed context props!
* Check the tests under "harmful context"!
*
* @static
* @throws Error
* @param {String} code - a string containing javascript code
* @param {Object} [context] - define globals, properties for evaluation context
* @return {Any} evaluated code
* @example
* var code = `{d: new Date('1970-01-01'), b: new Buffer('data')}`
* var res = saferEval(code, {Buffer: Buffer})
* // => toString.call(res.d) = '[object Date]'
* // => toString.call(res.b) = '[object Buffer]'
*/
function saferEval (code, context) {
'use strict'
return new SaferEval(context).runInContext(code)
}
module.exports = saferEval
module.exports.SaferEval = SaferEval