我正在构建一个涉及将用户输入重定向到服务器端命令的 Node.JS 应用程序。当然,这可能对安全性造成灾难性影响,因此我希望在SELinux 沙箱中运行子命令。(我不想在沙箱中运行整个应用程序,因为我希望最终用户在服务器上都有自己的工作区。)
例如,考虑命令cowsay
。为了运行沙盒牛话,您只需要sandbox cowsay
. 除了幕后的安全差异之外, 的接口sandbox cowsay
应该与 plain 的接口相同cowsay
。
然而,Node.JS 对这两种方法的反应不同。考虑代码:
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 将某些内容输入其标准输入,但沙盒仅以python
代码 0 存在,无需等待。
仅当 SELinux 处于“强制”模式时才会出现此行为。当 SELinux 处于“许可”(非强制)模式时,沙盒版本可以正常工作。
为了让 Node.JS 将沙盒命令与非沙盒命令相同,需要发生什么?