CocytusというJSを書きました。
こんな感じで使います。
<script src="cocytus.js"></script>
<script>
var jail = Cocytus();
jail.run(function() {
var l = 42;
postMessage(l);
g = 42; // see what happens in console
postMessage(g);
});
</script>
といってもピンと来ないかと思われるので、デモを用意しました。
要するに、 Web Worker で sandbox を実現したわけです。あくまで sandbox なので、呼び出し側の document には手をかけません。
で、何が禁止されてるかというと、こんな感じです。
大域変数の宣言と初期化
Crockfordも大喜び?
var v = 1; postMessage(v); // it is okay to get existing global vars postMessage(Object.getOwnPropertyNames(this)); // but you can't assign it... undefined = 1; // global object is frozen postMessage(undefined); // or set new global variable g = 1; postMessage(g);
eval()
あからさまな奴ばかりではなく…
postMessage(21+21);
postMessage(eval("21+21"));
やや控え目な奴や…
postMessage((function(){return 42})());
postMessage((new Function("return 42"))());
あまり控え目でない奴まで。副作用としてconstructor禁止になりはしますが。
postMessage((function(a){return a})(42));
postMessage(''.constructor.constructor('a', 'return a')(42));
Timeout
Cocytusは実行に制限を設けるのに加え、強制タイムアウトも実現しています。
function(){
var n = 0
setInterval(function(){ postMessage(n++) }, 100);
}
もちろんWorker側で自主的に切腹するのもありです。
function(){
var n = 0
setInterval(function(){ postMessage(n++) }, 100);
setTimeout(function(){ close() }, 500);
}
きっかけと名前の由来
これです。
404 Blog Not Found:javascript - eval(insecure.code).safely with(jail); //でもIEが - nene2001さんのコメント最近、必要が生じまして同様のJavaScript SandBox in pure JavaScriptに取り組んでおります。
コメント欄を見ての通り、元記事の方法はうまく行きません。
その一方、 Web Worker はかつて一部のブラウザーにのみ許された贅沢でした。それから幾星霜…ぼんやりとこの記事をiPad見ていたら、何事もなかったように動くではありませんか!
これと、ES5のObject.freeze()を組み合わせたら、もしかして…
いけました。ES5さまさまです。
とりあえず以下で動作する事を確認しています。
- iOS 6 (Safari & UIWebView)
- Safari 6 (Mac)
- Android 4.x (Chrome and Built-in Browsers of Nexus 7 and Galaxy 3)
- Chrome 25
- Firefox 19
- IE 10 (Windows 8)
名前の由来は、こちら。
コーキュートス - Wikipediaコーキュートス(Cocytus, 希: κωκυτός)はギリシア神話において、地下世界(地獄)の最下層に流れる川で、「嘆きの川」を意味する。元来は「悲嘆」を意味している。
Object.freeze()が決定的な役割を果たしているのでこれにしました。
Enjoy!
Dan, not Dante, the JavaScripter

このブログにコメントするにはログインが必要です。
さんログアウト
この記事には許可ユーザしかコメントができません。