Is it possible to restrict the scope of a javascript function?

Using embedded Web Workers could allow to run safe functions. Something like this allows a user to enter javascript, run it and get the result without having access to your global context.

globalVariable = "I'm global";

document.getElementById('submit').onclick = function() {
  createWorker();
}


function createWorker() {
  // The text in the textarea is the function you want to run
  var fnText = document.getElementById('fnText').value;

  // You wrap the function to add a postMessage 
  // with the function result
  var workerTemplate = "\
function userDefined(){" + fnText +
    "}\
postMessage(userDefined());\
onmessage = function(e){console.log(e);\
}"

  // web workers are normally js files, but using blobs
  // you can create them with strings.
  var blob = new Blob([workerTemplate], {
    type: "text/javascript"
  });

  var wk = new Worker(window.URL.createObjectURL(blob));
  wk.onmessage = function(e) {
    // you listen for the return. 
    console.log('Function result:', e.data);
  }

}
<div>Enter a javascript function and click submit</div>
<textarea id="fnText"></textarea>
<button id="submit">
  Run the function
</button>

You can try these for example by pasting it in the textarea:

return "I'm a safe function";

You can see that it's safe:

return globalVariable;

You can even have more complex scripts, something like this:

var a = 4, b = 5;
function insideFn(){
    // here c is global, but only in the worker context
    c = a + b;
}
insideFn();
return c;

See info about webworkers here, especially embedded web workers: https://developer.mozilla.org/en-US/docs/Web/API/Web_Workers_API/Using_web_workers#Embedded_workers


Run the code in an iframe hosted on a different Origin. This is the only way to guarantee that untrusted code is sandboxed and prevented from accessing globals or your page's DOM.