ユーザー入力をサーバー側コマンドにリダイレクトする Node.JS アプリケーションを構築しています。もちろん、それはセキュリティに壊滅的な影響を与える可能性があるため、子コマンドをSELinux サンドボックス内で実行したいと考えています。(アプリケーション全体をサンドボックス内で実行したくありません。これは、エンド ユーザーがそれぞれサーバー上に独自のワークスペースを持つことを望んでいるためです。)
たとえば、コマンドを考えてみましょうcowsay
。サンドボックス化されたカウセイを実行するには、単にsandbox cowsay
. 舞台裏のセキュリティの違いを除けば、 のインターフェースsandbox cowsay
は plain のインターフェースと同じでなければなりませんcowsay
。
ただし、Node.JS はこれら 2 つのアプローチに対して異なる対応をします。次のコードを検討してください。
var spawn = require('child_process').spawn;
var cmd = spawn("cowsay", ["hello"]); // line A (no sandbox)
var cmd = spawn("sandbox", ["cowsay", "hello"]); // line B (with sandbox)
cmd.stdout.on("data", function(data){
console.log("stdout: "+data);
});
cmd.stderr.on("data", function(data){
console.log("stderr: "+data);
});
cmd.on("exit", function(err){
console.log("exit: "+err);
});
行 A を含むバージョンの出力を次に示します。
$ node run.js
stdout: _______
< hello >
-------
\ ^__^
\ (oo)\_______
(__)\ )\/\
||----w |
|| ||
exit: 0
しかし、代わりにB行を含むバージョンの出力は次のとおりです。
$ node run.js
exit: 0
つまり、Node.JS はサンドボックスの子プロセスからストリームを読み取っていないようです。
このテストは、任意のコマンドを使用して実行できます。たとえば、python コマンド インタープリターを使用したとします。ここで何が起こるかというと、サンドボックスpython
化されていないものは Node.JS から stdin に何かが供給されるのを待ちますが、サンドボックス化されたものはpython
待機せずに単にコード 0 で存在します。
この動作は、SELinux が「enforcing」モードの場合にのみ発生します。サンドボックス バージョンは、SELinux が「許可」(非強制) モードの場合に正常に動作します。
Node.JS がサンドボックス化されたコマンドをサンドボックス化されていないコマンドと同じように扱うには、何が必要ですか?