11

文字列生成関数 (Function コンストラクターを使用) のアクセスを親/グローバル スコープに制限できますか?

例: 次のコードはそのままfalseを出力します。これは、関数が変数 a を window に格納/変更しているためです。

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

ウィンドウ/親スコープへのアクセスを制限して、「true」を出力することはできますか?

4

4 に答える 4

13

これは、Esailja の提案と合わせて非常に強力な追加のアイデアです (議論については、彼の回答に関するコメントを参照してください)。

ダミーの iframe を作成し、そのFunction機能を使用できます。それを使用して作成された関数は、デフォルトで iframe のスコープにのみアクセスできますが、それでも外れる可能性があります。幸いなことに、Esailja が提案したように、それを防ぐのは簡単です。

関数は次のようになると想像できます。

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)();
}

デモ

必要に応じ'use strict';て、コードの先頭に追加することもできます。


これは、少なくとも Chrome では機能します。この方法で作成された関数が iframe のグローバル スコープまたはページのグローバル スコープにアクセスできるかどうかは、次の方法で簡単にテストできます。

(function() {
    var frame = document.createElement('iframe');
    document.body.appendChild(frame);
    var same = window === frame.contentWindow.Function('return window;')();
    alert(same ? ':(' : ':)');
    document.body.removeChild(frame);
}());
于 2012-08-08T17:40:21.107 に答える
6

私はそうは思わない。保護するグローバルに名前を付けて、それらをシャドウすることができます。

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

しかし、この関数は、何を試してもグローバルにアクセスできるようになります...そのため、この関数はグローバルと呼ばれます。

何をしようとしているのかに応じて、Webワーカーなどの他の回避策があります...そしていつものように、隠されたiframeハック

于 2012-08-08T17:11:14.387 に答える
2

@Esailjaの答えは正しいです。さらに、最初に保護する必要があるグローバル変数の数を制限することをお勧めします。通常はグローバル名前空間に配置するAPPものを、制御するスコープに配置します。

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

グローバル スコープへのアクセスを完全に制限する方法はありませんが、少なくともこの方法では、1 つのオブジェクトのみを保護する必要がありますAPP

于 2012-08-08T17:19:22.917 に答える