Search code examples
javascriptglobal-variablesevalinformation-hiding

JavaScript - How to hide global scope from eval'd script


I usually think of global scope as a namespace that always can be accessed from everywhere. I would like to know whether it is theoretically possible to completely hide global scope. For example, assume we have some code we would like to evaluate (in the console of a browser):

var code = 
  "console.log(this);   " + // access the global object directly
  "console.log(window); " + // access the global object as the window object
  "newGlobalVar = 42;   ";  // implicitly create global object
eval(code);

By wrapping the eval call, this and window can be hidden from code:

(function (window) { eval(code); }).call({});

But I can't stop the code implicitly create global variables. Is it possible somehow? I don't want to use this stuff, I'm just curious.


Solution

  • If you're running in fairly modern browsers, you can mostly block window access by making a function that shadows the window and self variables with parameters, and runs the code in strict mode.

    var obj = {};
    
    var func = new Function("self", "window", "'use strict';" + code);
    
    func.call(obj, obj, obj);
    
    console.log(obj); // see if there were any attempts to set global variables.
    

    Any attempt to access window or self will merely access our obj object, and the value of this will also be our obj.

    Because we're in strict mode, implicit globals aren't allowed. Also, the default this value of functions will be undefined instead of window.

    I think there are a couple hacks that may get around this, but this should cover most scenarios.