Node.js:为 exec() 清理不受信任的用户输入

Node.js: Sanitize untrusted user input for exec()

小例子,从 REST API node.js app:

const { exec } = require('child_process');
var userInput = 'untrusted source';
var cmd = `/bin/echo "${userInput}"`;
exec(cmd, function(err, stdout, stderr) {
    console.log('echo: ' + stdout);
});

假设 userInput 来自不受信任的来源,需要做什么来避免任何漏洞?例如,echo 的引用 "${userInput}" 参数避免输入 'evil spirit; rm -rf /' 造成损坏。还需要做些什么来保证安全?

更新: objective 是为了使文件系统中现有的一些 shell scripts/commands 通过 REST [=29] =] 在 intranet.

根据 https://nodejs.org/api/child_process.html#child_process_child_process_spawn_command_args_options 的官方 Node.js child_process 文档,在 shell 脚本中使用用户输入而不对其进行清理是(显然)不安全的:

If the shell option is enabled, do not pass unsanitized user input to this function. Any input containing shell metacharacters may be used to trigger arbitrary command execution.

因此,这是我的问题中所述的示例,使用 spawn 而不是 exec 以安全的方式重写:

const { spawn } = require('child_process');

var userInput = 'untrusted source';
var args = [ userInput ];
var cmd = '/bin/echo';
var subprocess = spawn(cmd, args);
var stderr = '';
var stdout = '';
subprocess.stdout.on('data', function(data) {
    stdout += data;
});
subprocess.stderr.on('data', function(data) {
    stderr += data;
});
subprocess.on('close', function(exitCode) {
  console.log('echo: ' + stdout);
});

这是 CLI 包装器 Node.js 应用程序的简化代码片段,它使内部网络上的现有命令和 shell 脚本可以通过 REST API 以安全方式使用: https://github.com/peterthoeny/rest-cli-io