【问题标题】:Node.js: Sanitize untrusted user input for exec()Node.js:清理 exec() 的不受信任的用户输入
【发布时间】:2020-08-27 13:38:41
【问题描述】:

小例子,从 REST API node.js 应用程序简化:

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 /' 造成损坏。还需要做些什么来确保安全?

更新:目标是通过 intranet 上的 REST API 使文件系统中的一些现有 shell 脚本/命令可用。

【问题讨论】:

  • 转义所有反斜杠和引号,您将得到一个基本可以但仍然很幼稚的解决方案
  • 不要运行未经测试的代码。
  • @Kalycon:是的,反引号很明显,如 'untrusted `date`'
  • @GetOffMyLawn:“不要运行未经测试的代码”/“使用虚拟机”在这种情况下没有帮助。目标是通过 REST API 使 Intranet 上现有的特定 shell 脚本/命令可用(我更新了帖子以进行澄清)

标签: javascript node.js filter exec sanitization


【解决方案1】:

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

如果启用了 shell 选项,请不要将未经处理的用户输入传递给此函数。任何包含 shell 元字符的输入都可用于触发任意命令执行。

所以,这是我的问题中所述的示例,使用 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 应用程序的简化代码 sn-p,它通过 REST API 以安全的方式使内部网络上的现有命令和 shell 脚本可用:https://github.com/peterthoeny/rest-cli-io

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2016-05-17
    • 2021-10-31
    • 1970-01-01
    • 1970-01-01
    • 2013-09-14
    • 1970-01-01
    • 2019-05-26
    相关资源
    最近更新 更多