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

Posted

技术标签:

【中文标题】node.js 安全/转义中的 child_process 生成【英文标题】:child_process spawn in node.js security / escaping 【发布时间】:2014-07-05 01:06:07 【问题描述】:

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

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

【问题讨论】:

【参考方案1】:

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

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

对于一个简单的 ls -l 可能需要用户输入的 .exec(),生成的系统调用看起来像这样。

[pid 25170] execve("/bin/sh", ["/bin/sh", "-c", "ls -l 用户输入"], [/* 16 个变量 */]

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

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

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

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

因此,以下是从 node.js 运行系统命令的通用集体指南:

避免使用 child_process.exec,如果命令包含根据用户输入更改的任何输入,则切勿使用它。 尽可能避免让用户将选项传递给命令。使用 spawn 或 execfile 时,通常值是可以的,但通过用户控制的字符串选择选项是个坏主意。 如果您必须允许用户控制的选项,请仔细查看命令的选项,确定哪些选项是安全的,然后仅将这些选项列入白名单。

【讨论】:

使用多个命令怎么样?例如 "cd" + dir + "; ./" + fileToExecute。我猜你用你描述的方式是做不到的。我错了吗?

以上是关于node.js 安全/转义中的 child_process 生成的主要内容,如果未能解决你的问题,请参考以下文章

[js高手之路]Node.js模板引擎教程-jade速学与实战2-流程控制,转义与非转义

在 Node.js 中添加转义时无法读取属性长度

Node JS readFileSync严格模式下不允许八进制转义序列

Node.js开发 ---- ejs源码转译

Node.js中的不安全跳转如何防御详解

Node.js Connect session() 参数中的安全选项是啥