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

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

我将用户提交的信息传递给GM​​。 是否有安全问题,用户可以使用pipe道(或其他命令行欺骗)进行某种注入攻击? 还是spawn保护呢? 如果不是的话,在这种情况下是否有逃避用户提交值的最佳做法?

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

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

由此产生的系统调用看起来像.exec()这样一个简单的ls -l可能需要用户input。

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

由于gm使用产生的结果系统调用将看起来像这样。

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

因为GM将是execve的第一个参数。 这意味着用户不能在shell中使用pipe道和其他命令行欺骗来运行子命令,因为在我们的例子中/ bin / ls不知道如何使用反引号或pipe道。 / bin / bash将会解释这些命令。 这与使用参数化和基于string的SQL查询类似,如果你熟悉的话。

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

所以,下面是从node.js运行系统命令的通用集体指导:

  • 避免使用child_process.exec,如果命令包含任何根据用户input而改变的input,请不要使用它。
  • 尽可能避免让用户传递选项给命令。 通常值使用spawn或execfile时可以,但通过用户控制的stringselect选项是一个坏主意。
  • 如果您必须允许用户控制选项,请广泛查看该命令的选项,确定哪些选项是安全的,并仅将这些选项列入白名单。