child_process在node.js安全/转义中生成

时间:2022-12-02 00:01:23

In Node, I'm using a module (GM) and noticed that it uses spawn from the child_process module to pass arguments to GraphicMagick's convert executable.

在Node中,我正在使用一个模块(GM)并注意到它使用了来自child_process模块​​的spawn来将参数传递给GraphicMagick的convert可执行文件。

I'm passing user-submitted information to GM. Is there a security concern that the user could do some sort of injection attack using a pipe (or other command line trickery)? Or does spawn protect against that? If not, is there a best practice for escaping user submitted values in this case?

我正在将用户提交的信息传递给GM​​。是否存在安全问题,用户可以使用管道(或其他命令行欺骗)进行某种注入攻击?或者产卵可以防止这种情况发生吗?如果没有,在这种情况下是否有最佳做法可以转义用户提交的值?

1 个解决方案

#1


7  

We recently published a blog post on avoiding command injection vulnerabilities in node.js. It explains a bit about how spawn prevents this.

我们最近发布了一篇关于避免node.js中的命令注入漏洞的博客文章。它解释了一下spawn如何防止这种情况。

If gm was using child_process.exec there would be a greater chance of injection. This is because child_process.exec executes the commands under a subshell and not directly, letting shell meta characters like backticks, $(), ;, &&, || etc to be used nefariously.

如果gm使用child_process.exec,那么注入的可能性会更大。这是因为child_process.exec在子shell下执行命令而不是直接执行命令,让shell元字符像反引号,$(),;,&&,||邪恶地使用等。

The resulting system call looks like this with .exec() for a simple ls -l that might take user input.

对于可能需要用户输入的简单ls -l,生成的系统调用与.exec()类似。

[pid 25170] execve("/bin/sh", ["/bin/sh", "-c", "ls -l user input"], [/* 16 vars */]

[pid 25170] execve(“/ bin / sh”,[“/ bin / sh”,“ - c”,“ls -l user input”],[/ * 16 vars * /]

Since gm uses spawn the resulting system call would look something like this.

由于gm使用spawn,因此生成的系统调用看起来像这样。

[pid 25565] execve("/bin/ls", ["/bin/ls", "-l", "."], [/* 16 vars */]

[pid 25565] execve(“/ bin / ls”,[“/ bin / ls”,“ - l”,“。”],[/ * 16 vars * /]

As gm would be the first argument to execve. This means that a user cannot run subcommands in the shell using pipes and other command line trickery, because in our example /bin/ls has no idea what to do with backticks or pipes or ;. It’s /bin/bash that is going to be interpreting those commands. It’s similar to using parametrized vs string-based SQL queries, if you are familiar with that.

因为gm将是第一个执行的论据。这意味着用户无法使用管道和其他命令行技巧在shell中运行子命令,因为在我们的示例中/ bin / ls不知道如何处理反引号或管道或;它是/ bin / bash将解释这些命令。如果您熟悉它,则类似于使用参数化和基于字符串的SQL查询。

This does however come with a caveat: using spawn is not always a safe thing. User provided arguments could still potentially have a bad outcome, maybe not command injection but something else. Check with the behavior of gm and the arguments that you are pass in user provided input into and think about how the user might be able to abuse that argument.

然而,这确实有一个警告:使用spawn并不总是一件安全的事情。用户提供的参数可能仍然可能有不好的结果,可能不是命令注入,而是其他东西。检查gm的行为以及您在用户提供的输入中传递的参数,并考虑用户可能如何滥用该参数。

So, here’s the generic collective guidance for running system commands from node.js:

所以,这是从node.js运行系统命令的通用集合指南:

  • Avoid using child_process.exec, and never use it if the command contains any input that changes based on user input.
  • 避免使用child_process.exec,如果命令包含任何基于用户输入而更改的输入,则永远不要使用它。

  • Try to avoid letting users pass in options to commands if possible. Typically values are okay when using spawn or execfile, but selecting options via a user controlled string is a bad idea.
  • 尽可能避免让用户将选项传递给命令。通常,使用spawn或execfile时值是可以的,但通过用户控制的字符串选择选项是个坏主意。

  • If you must allow for user controlled options, look at the options for the command extensively, determine which options are safe, and whitelist only those options.
  • 如果必须允许用户控制的选项,请广泛查看命令的选项,确定哪些选项是安全的,并将这些选项列入白名单。

#1


7  

We recently published a blog post on avoiding command injection vulnerabilities in node.js. It explains a bit about how spawn prevents this.

我们最近发布了一篇关于避免node.js中的命令注入漏洞的博客文章。它解释了一下spawn如何防止这种情况。

If gm was using child_process.exec there would be a greater chance of injection. This is because child_process.exec executes the commands under a subshell and not directly, letting shell meta characters like backticks, $(), ;, &&, || etc to be used nefariously.

如果gm使用child_process.exec,那么注入的可能性会更大。这是因为child_process.exec在子shell下执行命令而不是直接执行命令,让shell元字符像反引号,$(),;,&&,||邪恶地使用等。

The resulting system call looks like this with .exec() for a simple ls -l that might take user input.

对于可能需要用户输入的简单ls -l,生成的系统调用与.exec()类似。

[pid 25170] execve("/bin/sh", ["/bin/sh", "-c", "ls -l user input"], [/* 16 vars */]

[pid 25170] execve(“/ bin / sh”,[“/ bin / sh”,“ - c”,“ls -l user input”],[/ * 16 vars * /]

Since gm uses spawn the resulting system call would look something like this.

由于gm使用spawn,因此生成的系统调用看起来像这样。

[pid 25565] execve("/bin/ls", ["/bin/ls", "-l", "."], [/* 16 vars */]

[pid 25565] execve(“/ bin / ls”,[“/ bin / ls”,“ - l”,“。”],[/ * 16 vars * /]

As gm would be the first argument to execve. This means that a user cannot run subcommands in the shell using pipes and other command line trickery, because in our example /bin/ls has no idea what to do with backticks or pipes or ;. It’s /bin/bash that is going to be interpreting those commands. It’s similar to using parametrized vs string-based SQL queries, if you are familiar with that.

因为gm将是第一个执行的论据。这意味着用户无法使用管道和其他命令行技巧在shell中运行子命令,因为在我们的示例中/ bin / ls不知道如何处理反引号或管道或;它是/ bin / bash将解释这些命令。如果您熟悉它,则类似于使用参数化和基于字符串的SQL查询。

This does however come with a caveat: using spawn is not always a safe thing. User provided arguments could still potentially have a bad outcome, maybe not command injection but something else. Check with the behavior of gm and the arguments that you are pass in user provided input into and think about how the user might be able to abuse that argument.

然而,这确实有一个警告:使用spawn并不总是一件安全的事情。用户提供的参数可能仍然可能有不好的结果,可能不是命令注入,而是其他东西。检查gm的行为以及您在用户提供的输入中传递的参数,并考虑用户可能如何滥用该参数。

So, here’s the generic collective guidance for running system commands from node.js:

所以,这是从node.js运行系统命令的通用集合指南:

  • Avoid using child_process.exec, and never use it if the command contains any input that changes based on user input.
  • 避免使用child_process.exec,如果命令包含任何基于用户输入而更改的输入,则永远不要使用它。

  • Try to avoid letting users pass in options to commands if possible. Typically values are okay when using spawn or execfile, but selecting options via a user controlled string is a bad idea.
  • 尽可能避免让用户将选项传递给命令。通常,使用spawn或execfile时值是可以的,但通过用户控制的字符串选择选项是个坏主意。

  • If you must allow for user controlled options, look at the options for the command extensively, determine which options are safe, and whitelist only those options.
  • 如果必须允许用户控制的选项,请广泛查看命令的选项,确定哪些选项是安全的,并将这些选项列入白名单。