Giter VIP home page Giter VIP logo

notevil's Introduction

No longer maintained. Do not use.

notevil's People

Contributors

cecchi avatar dominictarr avatar kumavis avatar mmckegg avatar phra avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

notevil's Issues

Execution timeout

I know right now it's solved by iteration counter, but it might not be enough, or something you don't ecxactly need

I think adding optional parameter would be good option, but checking if time is out after each operation might be waste of resources. Maybe wrapping it in worker would be better solution?

I will try to prepare a pull request with that feature.

Strange Issue with empty object

source from esprima

function () {
    var name, types = {};
    if (typeof Object.create === 'function') {
        types = Object.create(null);
    }
    for (name in Syntax) {
        if (Syntax.hasOwnProperty(name)) {
            types[name] = Syntax[name];  //gets stuck here. object is 'types'.
        }
    }
    if (typeof Object.freeze === 'function') {
        Object.freeze(types);
    }
    return types;
}()

Does not break when accessing members of objects undefined in context

var safeEval = require('notevil')
safeEval('y.u.no.error')
//=> undefined
safeEval('y.u.no.error', {})
//=> undefined
safeEval('y.u.no.error',{y:null})
//=> TypeError: Cannot read property 'u' of null
safeEval('y.u.no.error',{y:undefined})
//=> TypeError: Cannot read property 'u' of undefined

Get exposed variables from script

I have a project that interprets inline JS like this:

$: var key = "val";

Is there a way to expose 'key' to a provided context when evaling?

This is what I'm hoping for:

var ctx = {};
notevil('let x = 0;', ctx);
console.log(ctx.x);
//0

Obviously I could require the developer to return an object with the exposed variable names like this:

var code = `
  let x = 10;
  Object({ x }); //expose everything wrapped here
`;

I would have to do my own mixin on the ctx object and it would be a valid workaround. It's just more work for my developers.

Expose types by default

Types should be exposed by default. Since their literals are exposed the types are already exposed through round-about means. I would consider any type that has a literal to be a basic and essential 'Language Feature'. These structures could still be overwritten via the included context hash.

Array = [].constructor
Object = ({}).constructor
String = "".constructor

failing types tests here: #12

Trying to get in touch regarding a security issue

Hi there,

I couldn't find a SECURITY.md in your repository and am not sure how to best contact you privately to disclose a security issue.

Can you add a SECURITY.md file with an e-mail to your repository, so that our system can send you the vulnerability details? GitHub suggests that a security policy is the best way to make sure security issues are responsibly disclosed.

Once you've done that, you should receive an e-mail within the next hour with more info.

Thanks! (cc @huntr-helper)

Hoisting is naïve

naïve hoisting causes problem when attempting to safeEval the following code

var names = [ ... ]
var primitives = names.map(getGlobal);
function getGlobal(){ ... }

Here is this project's own primitives.js after hoisting

{
    var global = self;
    var names = [
            'Object',
            'String',
            'Boolean',
            'Number',
            'RegExp',
            'Date',
            'Array'
        ];
    var immutable = {
            string: 'String',
            boolean: 'Boolean',
            number: 'Number'
        };
    var primitives = names.map(getGlobal);
    var protos = primitives.map(getProto);
    var protoReplacements = {};
    module.exports = Primitives;
    function Primitives(context) {
        if (this instanceof Primitives) {
            this.context = context;
            for (var i = 0; i < names.length; i++) {
                if (!this.context[names[i]]) {
                    this.context[names[i]] = wrap(primitives[i]);
                }
            }
        } else {
            return new Primitives(context);
        }
    }
    Primitives.prototype.replace = function (value) {
        var primIndex = primitives.indexOf(value);
        var protoIndex = protos.indexOf(value);
        if (~primIndex) {
            var name = names[primIndex];
            return this.context[name];
        } else if (~protoIndex) {
            var name = names[protoIndex];
            return this.context[name].prototype;
        } else {
            return value;
        }
    };
    Primitives.prototype.getPropertyObject = function (object, property) {
        if (immutable[typeof object]) {
            return this.getPrototypeOf(object);
        }
        return object;
    };
    Primitives.prototype.isPrimative = function (value) {
        return !!~primitives.indexOf(value) || !!~protos.indexOf(value);
    };
    Primitives.prototype.getPrototypeOf = function (value) {
        if (value == null) {
            return value;
        }
        var immutableType = immutable[typeof value];
        if (immutableType) {
            var proto = this.context[immutableType].prototype;
        } else {
            var proto = Object.getPrototypeOf(value);
        }
        if (!proto || proto === Object.prototype) {
            return null;
        } else {
            var replacement = this.replace(proto);
            if (replacement === value) {
                replacement = this.replace(Object.prototype);
            }
            return replacement;
        }
    };
    function getProto(func) {
        return func.prototype;
    }
    function getGlobal(str) {
        return global[str];
    }
    function setProto(obj, proto) {
        obj.__proto__ = proto;
    }
    function wrap(prim) {
        var proto = Object.create(prim.prototype);
        var result = function () {
            if (this instanceof result) {
                prim.apply(this, arguments);
            } else {
                var instance = prim.apply(null, arguments);
                setProto(instance, proto);
                return instance;
            }
        };
        setProto(result, prim);
        result.prototype = proto;
        return result;
    }
}

UnaryExpression delete

I have an example object here that you can use reproduce this error

var r=[{
	"_id": "BLOCKS",
	"type": "cache",
	"cache": {
		"0000000000260dfd032cb5bc302a3307fe141c7e505b53214a6b7c1703ab9b6b": {
			"height": 1087605,
			"block": "confirmed-block",
			"from": "blockio_blk"
		},
		"00000000000004e108a232adc26102f18388762f18d459952177f486918bbf3f": {
			"height": 1087607,
			"block": "confirmed-block",
			"from": "blockio_blk"
		},
		"00000000004e2a0b541e5a95f6e714e75dcf89964a69bfc34bf615465ef04a74": {
			"height": 1087606,
			"block": "confirmed-block",
			"from": "blockio_blk"
		},
		"00000000a8fc15b379ab82bf3ad04c92b26995c679596cc52ce47791dc751028": {
			"height": 1087608,
			"block": "confirmed-block",
			"from": "blockio_blk"
		},
		"0000000000000255c45f107736f106a4c56d33bb585b3b6f506f8189dafd1330": {
			"height": 1087609,
			"block": "confirmed-block",
			"from": "blockio_blk"
		},
	}
}];

Normal eval works fine:

eval('for(var i in r[0].cache){if(r[0].cache[i].height>5){delete r[0].cache[i];}}');
console.log(r);

[ { _id: 'BLOCKS', type: 'cache', cache: {} } ]

notevail gets error

require('notevil')('for(var i in r[0].cache){if(r[0].cache[i].height>5){delete r[0].cache[i];}}',{r:r});

Error: Unsupported expression: UnaryExpression
at unsupportedExpression (/var/sentora/hostdata/zadmin/node_modules/notevil/index.js:416:13)
at walk (/var/sentora/hostdata/zadmin/node_modules/notevil/index.js:260:27)
at walk (/var/sentora/hostdata/zadmin/node_modules/notevil/index.js:103:16)
at walkAll (/var/sentora/hostdata/zadmin/node_modules/notevil/index.js:61:16)
at walk (/var/sentora/hostdata/zadmin/node_modules/notevil/index.js:79:22)
at walk (/var/sentora/hostdata/zadmin/node_modules/notevil/index.js:161:18)
at walkAll (/var/sentora/hostdata/zadmin/node_modules/notevil/index.js:61:16)
at walk (/var/sentora/hostdata/zadmin/node_modules/notevil/index.js:79:22)
at walk (/var/sentora/hostdata/zadmin/node_modules/notevil/index.js:207:19)
at walkAll (/var/sentora/hostdata/zadmin/node_modules/notevil/index.js:61:16)

The error object looks like

"error": {
				"node": {
					"type": "UnaryExpression",
					"operator": "delete",
					"argument": {
						"type": "MemberExpression",
						"computed": true,
						"object": {
							"type": "MemberExpression",
							"computed": false,
							"object": {
								"type": "MemberExpression",
								"computed": true,
								"object": {
									"type": "Identifier",
									"name": "r"
								},
								"property": {
									"type": "Literal",
									"value": 0
								}
							},
							"property": {
								"type": "Identifier",
								"name": "cache"
							}
						},
						"property": {
							"type": "Identifier",
							"name": "i"
						}
					},
					"prefix": true
				}

notevil is supporting the in operator

For example:
var condition = (1 in [1,2,3]);
Need to check the condition as safeEval(condition);

This above statement is execute or not.

Can someone help me out?

NewExpression - Support the 'new' keyword

"new Boolean(true)"  
├─ type: Program
└─ body
   └─ 0
      ├─ type: ExpressionStatement
      └─ expression
         ├─ type: NewExpression
         ├─ callee
         │  ├─ type: Identifier
         │  └─ name: Boolean
         └─ arguments
            └─ 0
               ├─ type: Literal
               └─ value: true

block everything

Am I able to completely block everything, even while loops? I want an environment with everything that can be ran explicitly approved.

Typescript support

I'm trying to use this library in a typescript project. But typescript/rollup throws error during compilation step.
Is there any plan to support typescript?

Unsupported ThisExpression

safeEval('this')
//=> Object {type: "ThisExpression"} index.js:11
//=> Uncaught Error: Unsupported expression.

Not sure what should happen, but thought I should open an issue to discuss.

Stream interface?

When user is downloading a large js, this module can compile it on the fly.

malicious regular expressions

This is vunerable to evil regular expressions. It's possible to construct a regular expression that executes in exponential time, which won't look like an obvious infinite loop, but will lock the cpu for a while.

require('notevil')("/((a+)+)b/.test('aaaaaaaaaaaaaaaaaaaaaaaaaaaaa')")

This tricks the regex evaluator into searching for all possible ways to arrange the two nested a groups,
(since the string is missing a b at the end it will continue searching, if it had a b it would return as soon as it has found a match)

the simplest way to prevent this is just to block regular expressions with a starheight > 1 (i.e. with nested groups) this may block some non-evil regular expressions, but is much simpler than implementing a regular expression interpreter.

for more detail: http://perlgeek.de/blog-en/perl-tips/in-search-of-an-exponetial-regexp.html

also, @substack has a module for detecting safe regular expressions: https://github.com/substack/safe-regex

Exception thrown while running in node v6 with ECMAScript 2015 syntax

Code

const safeEval = require('notevil');
const source = `
    return inputs.map((v) => v + 1);
`;

try {
    const h = safeEval.Function('inputs', source);
    const o = h([1, 2, 3]);
    conosle.log('===', o);
} catch(err) {
    console.log(err);
}

Expect

===, [ 2, 3, 4 ]

Actually

{ Error: Line 2: Unexpected token >
    at throwError (/Users/adoyle/Workspace/Ali/wormholes-system-plugins/node_modules/[email protected]@esprima/esprima.js:1156:21)
    at throwUnexpected (/Users/adoyle/Workspace/Ali/wormholes-system-plugins/node_modules/[email protected]@esprima/esprima.js:1213:9)
    at parsePrimaryExpression (/Users/adoyle/Workspace/Ali/wormholes-system-plugins/node_modules/[email protected]@esprima/esprima.js:1567:16)
    at parseLeftHandSideExpressionAllowCall (/Users/adoyle/Workspace/Ali/wormholes-system-plugins/node_modules/[email protected]@esprima/esprima.js:1644:61)
    at parsePostfixExpression (/Users/adoyle/Workspace/Ali/wormholes-system-plugins/node_modules/[email protected]@esprima/esprima.js:1703:20)
    at parseUnaryExpression (/Users/adoyle/Workspace/Ali/wormholes-system-plugins/node_modules/[email protected]@esprima/esprima.js:1784:16)
    at parseMultiplicativeExpression (/Users/adoyle/Workspace/Ali/wormholes-system-plugins/node_modules/[email protected]@esprima/esprima.js:1790:20)
    at parseAdditiveExpression (/Users/adoyle/Workspace/Ali/wormholes-system-plugins/node_modules/[email protected]@esprima/esprima.js:1807:20)
    at parseShiftExpression (/Users/adoyle/Workspace/Ali/wormholes-system-plugins/node_modules/[email protected]@esprima/esprima.js:1824:20)
    at parseRelationalExpression (/Users/adoyle/Workspace/Ali/wormholes-system-plugins/node_modules/[email protected]@esprima/esprima.js:1845:16)
index: 41, lineNumber: 2, column: 28 }

Version

node version: v6.9.1

Unexpected expression: 'WithStatement'

I'm currently trying to implement notevil 1.1.0 into Vue to create a Vue 2.6-csp build. However I'm running into the fact that with statements are used in Vue and notevil throws an error for these statements: https://github.com/mmckegg/notevil/blob/master/index.js#L368

In Vue I am able to find the following code which probably triggers this (https://github.com/vuejs/vue/blob/2.6/src/compiler/codegen/index.js#L49):

with(this){return ${code}}

And somewhere in the code following where that line is executed by:

return new Function(code)

Which I have tried to replace with:

const fn = notevil.Function(code);
        return function() {
            return fn.call(this);
        };

Where I have tried to inject the this property to be used in the with(this) expression.

The result is a Unexpected expression: 'WithStatement' error in my console.

Is it possible to add the ability to parse with statements? Or does anyone have suggestions on how to work around the with(this) expressions?

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.