Skip to content Skip to sidebar Skip to footer

How Can I Detect I'm Inside An Eval() Call?

Does there exist a string s such that (new Function(s))(); and eval(s); behave differently? I'm trying to 'detect' how a string is being evaluated.

Solution 1:

Check for the arguments object. If it exists, you're in the function. If it doesn't it has been evaled.

Note that you'll have to put the check for arguments in a try...catch block like this:

var s = 'try {document.writeln(arguments ? "Function" : "Eval") } catch(e) { document.writeln("Eval!") }';
(newFunction(s))();
eval(s);

Demo

Solution to nnnnnn's concern. For this, I've edited the eval function itself:

var _eval = eval;
eval = function (){
    // Your custom code here, for when it's eval
    _eval.apply(this, arguments);
};

functiontest(x){
    eval("try{ alert(arguments[0]) } catch(e){ alert('Eval detected!'); }");
}
test("In eval, but it wasn't detected");​

Solution 2:

The current answer does not work in strict mode since you can't redefine eval. Moreover, redefining eval is problematic for many other reasons.

The way to differenciate them is based on the fact that well... one of them creates a function and what doesn't. What can functions do? They can return stuff :)

We can simply exploit that and do something with return:

// is in functiontry {
     returntrue;
} catch(e) { // in JS you can catch syntax errorsfalse; //eval returns the return of the expression.
}

So in example:

var s = "try{ return true; }catch(e){ false; }";
eval(s); // falseFunction(s)(); // true
(newFunction(s))(); // true, same as line above
(function(){ returneval(s); })(); // the nested 'problematic' case - false

Solution 3:

if (newError().stack.indexOf('at eval') > -1) {
    console.log('Oh noo, I am being evaled');
}

Post a Comment for "How Can I Detect I'm Inside An Eval() Call?"