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