文字列生成関数 (Function コンストラクターを使用) のアクセスを親/グローバル スコープに制限できますか?
例: 次のコードはそのままfalseを出力します。これは、関数が変数 a を window に格納/変更しているためです。
window.a = 4;
Function("a=3;")()
console.log(a === 4);
ウィンドウ/親スコープへのアクセスを制限して、「true」を出力することはできますか?
文字列生成関数 (Function コンストラクターを使用) のアクセスを親/グローバル スコープに制限できますか?
例: 次のコードはそのままfalseを出力します。これは、関数が変数 a を window に格納/変更しているためです。
window.a = 4;
Function("a=3;")()
console.log(a === 4);
ウィンドウ/親スコープへのアクセスを制限して、「true」を出力することはできますか?
これは、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);
}());
私はそうは思わない。保護するグローバルに名前を付けて、それらをシャドウすることができます。
window.a = 4;
Function("a", "a=3;")()
console.log(a === 4);
しかし、この関数は、何を試してもグローバルにアクセスできるようになります...そのため、この関数はグローバルと呼ばれます。
何をしようとしているのかに応じて、Webワーカーなどの他の回避策があります...そしていつものように、隠されたiframeハック。
@Esailjaの答えは正しいです。さらに、最初に保護する必要があるグローバル変数の数を制限することをお勧めします。通常はグローバル名前空間に配置するAPP
ものを、制御するスコープに配置します。
var APP = (function() {
return {
a: 4
};
}());
グローバル スコープへのアクセスを完全に制限する方法はありませんが、少なくともこの方法では、1 つのオブジェクトのみを保護する必要がありますAPP
。