How can I detect I'm inside an eval() call?

后端 未结 3 881
佛祖请我去吃肉
佛祖请我去吃肉 2021-02-01 06:40

Does there exist a string s such that

(new Function(s))();

and

eval(s);

behave differently? I\'

相关标签:
3条回答
  • 2021-02-01 07:08
    if (new Error().stack.indexOf('at eval') > -1) {
        console.log('Oh noo, I am being evaled');
    }
    
    0 讨论(0)
  • 2021-02-01 07:17

    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!") }';
    (new Function(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);
    };
    
    function test(x){
        eval("try{ alert(arguments[0]) } catch(e){ alert('Eval detected!'); }");
    }
    test("In eval, but it wasn't detected");​
    
    0 讨论(0)
  • 2021-02-01 07:25

    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 function
    try {
         return true;
    } catch(e) { // in JS you can catch syntax errors
         false; //eval returns the return of the expression.
    }
    

    So in example:

    var s = "try{ return true; }catch(e){ false; }";
    eval(s); // false
    Function(s)(); // true
    (new Function(s))(); // true, same as line above
    (function(){ return eval(s); })(); // the nested 'problematic' case - false
    
    0 讨论(0)
提交回复
热议问题