web-dev-qa-db-ja.com

安全にサンドボックスし、ユーザーが送信したJavaScriptを実行しますか?

ユーザーが任意のJavaScriptコードを送信できるようにしたいと思います。これは、Node.JSサーバーに送信され、出力が複数のクライアントに(JSONとして)返される前に安全に実行されます。 eval関数が思い浮かびますが、これには複数のセキュリティ上の問題があることを知っています(ユーザーが送信したコードはノードのファイルAPIにアクセスできるなど)。 Microsoft Web SandboxやGoogle Cajaなど、サニタイズされたマークアップとスクリプトの実行を許可するプロジェクト(ウェブサイトにサードパーティの広告を埋め込むため)を見たことがありますが、これらはクライアント側のツールであり、できるかどうかはわかりませんノード内で安全に使用できます。

Nodeで信頼できないJavaScriptをサンドボックス化して実行し、出力を取得する標準的な方法はありますか?このサーバー側を試してみるのは間違いですか?

EDIT:ユーザーがJavaScriptのすべての機能を利用できることは重要ではありません。実際には、どれを選択して選択できることが望ましいでしょう。 APIはユーザーコードに提供されます。

EDIT:私は先に進み、見つけたもので更新します。このサンドキャッスルモジュール( bcoe/sandcastle )は、私が考えていることをすることを目指しているようです。どれほど安全かはわかりませんが、これはあまり重要ではないので、試してみようと思います。これがうまくできた場合は、自分の答えを追加します。

43
Cory Gross

gf3はサンドボックスの破壊に対する保護を提供しないため、この回答は古くなっています

http://gf3.github.io/sandbox/ -require('child_process')ではなくrequire('vm')を使用します。

4
Ginden

Vm.runInContext( 'js code'、context)を使用してnodejsでサンドボックスサポートを使用できます。APIドキュメントのサンプル:

https://nodejs.org/api/vm.html#vm_vm_runinthiscontext_code_options

const util = require('util');
const vm = require('vm');

const sandbox = { globalVar: 1 };
vm.createContext(sandbox);

for (var i = 0; i < 10; ++i) {
    vm.runInContext('globalVar *= 2;', sandbox);
}
console.log(util.inspect(sandbox));

// { globalVar: 1024 }

警告:「s4y」で指摘されているように、欠陥があるようです。コメントをご覧ください。

10
ton

Node.jsの下では、サンドボックス化された子プロセスを作成できますが、"use strict";を使用してコードを追加する必要があります。追加しない場合、arguments.callee.callerを使用してサンドボックスを分割できます。

サンドボックス化されたWebワーカーでもコードが実行される可能性があるため、サーバーに送信する必要がある理由がわかりません。

また、Node.jsとWebブラウザーの両方について言及したすべてを簡素化し、さらに一連の関数をサンドボックスにエクスポートする機会を提供する、私の Jailed ライブラリを見てください。

4
asvd

1つの代替案は http://github.com/patriksimek/vm2 を使用することです。

$ npm install vm2

次に:

const {VM} = require('vm2');
const vm = new VM();

vm.run(`1 + 1`);  // => 2

他の回答のコメントで述べたように。

安全性はわかりませんが、少なくとも信頼されていないコードが安全に実行されていると(READMEで)主張されています。そして、ここの他の回答で提案されている解決策については、明らかなセキュリティの問題を見つけることができませんでした。

4

使用方法によっては、gVisorなどの仮想環境でサンドボックスを保護することも検討することをお勧めします。あなたはいくつかの情報を見つけることができます ここ

0
Pål Thingbø