最新消息:雨落星辰是一个专注网站SEO优化、网站SEO诊断、搜索引擎研究、网络营销推广、网站策划运营及站长类的自媒体原创博客

scope - Make sandbox around Function() in Javascript - Stack Overflow

programmeradmin10浏览0评论

Can I limit the access of a string-generated function (using the Function constructor) to the parent/global scopes?

For example: the following code, as it is, prints false, because the function is storing/modifying the variable a in window.

window.a = 4;
Function("a=3;")()
console.log(a === 4);

Could I restrict the access to window/parent scope and make it print out "true"?

Can I limit the access of a string-generated function (using the Function constructor) to the parent/global scopes?

For example: the following code, as it is, prints false, because the function is storing/modifying the variable a in window.

window.a = 4;
Function("a=3;")()
console.log(a === 4);

Could I restrict the access to window/parent scope and make it print out "true"?

Share Improve this question edited Aug 8, 2012 at 17:12 FRD asked Aug 8, 2012 at 17:04 FRDFRD 2,2543 gold badges19 silver badges24 bronze badges
Add a ment  | 

4 Answers 4

Reset to default 14

Here is an additional idea which could be quite powerful together with Esailija's proposal (see the ments on his answer for the discussion).

You could create dummy iframe and use its Function function. The function created with that will only have access to the scope of the iframe by default, though it could still break out of it. Fortunately it is easy to prevent that, by the way Esailija suggested.

I could imagine the function to be like this:

function sandboxed(code) {
    var frame = document.createElement('iframe');
    document.body.appendChild(frame);

    var F = frame.contentWindow.Function,
        args = Object.keys(frame.contentWindow).join();

    document.body.removeChild(frame);

    return F(args, code)();
}

DEMO

Optionally you might want to prepend 'use strict'; to the code.


This works at least in Chrome. Whether the function created this way has access to the iframe's global scope or the page's global scope can be easily tested with:

(function() {
    var frame = document.createElement('iframe');
    document.body.appendChild(frame);
    var same = window === frame.contentWindow.Function('return window;')();
    alert(same ? ':(' : ':)');
    document.body.removeChild(frame);
}());

I don't think so. You could name the globals you want to protect in the parameters so that they shadow them:

window.a = 4;
Function("a", "a=3;")()
console.log(a === 4);

But the function is going to have access to global no matter what you try... that's why it's called global.

Depending on what you are trying to do, there are other work-arounds such as web workers... and as always, hidden iframe hacks.

@Esailija's answer is right. Additionally, I would remend limiting the number of global variables that you have to protect in the first place. Put anything that you would normally put in the global namespace in an APP scope that you control:

var APP = (function() {
    return {
        a: 4
    };
}());

There's no way to pletely limit access to the global scope, but at least this way you only need to protect one object: APP.

Here's my adapted sandboxed function. It takes code and an optional dictionary with arguments to the function.

function sandboxed(code, args = {}) {
    var frame = document.createElement('iframe');
    document.body.appendChild(frame);
    var F = frame.contentWindow.Function;
    document.body.removeChild(frame);
    return F(...Object.keys(args), "'use strict';" + code)(...Object.values(args));
}

console.log(sandboxed('return a - 10;', {'a': 34}));

// 24
发布评论

评论列表(0)

  1. 暂无评论