在这篇文章中,我们将
学习如何使用js调用
系统命令的
正确以避免常见的命令行注入漏洞。
我们
经常使用的调用命令的
方法是最简单的child_process.exec.it有一个非常简单的使用方式;通过在一个字符串命令并返回一个
错误或命令的
处理结果对回调
函数。
这里是你调用系统命令通过一个非常典型的例子child_process.exec。
复制代码代码如下所示:
child_process.exec(' ',
功能(呃,数据){
console.log(数据);
});
但是,当您需要向您所调用的命令添加一些
用户输入参数时,会发生什么
情况呢显而易见的
解决方案是直接使用命令将用户合并成字符串。然而,我多年的经验告诉我,当你把一个字符串从一个系统发送到另一个系统时,总有一天会有问题。
复制代码代码如下所示:
用户输入;
child_process.exec('我' +
路径功能(呃,数据){
console.log(数据);
});
为什么
连接字符串会出现问题
嗯,因为child_process.exec引擎下,呼叫将被称为 /斌/ SH。没有
目标程序。发送的命令是通过一个新的 /斌/ sh'process
执行shell,child_process.exec
名字误导-这是一个bash解释器,不是一个计划。这意味着壳牌所有字符可能如果用户的输入参数,直接执行有毁灭性的后果。
复制代码代码如下所示:
{ 25170 } execve(PID /斌/ SH
例如,攻击者可以使用分号 结束命令并
启动一个新的调用。他们可以使用子引号或$()来
运行子命令,也有很多潜在的滥用。
那么,正确的称呼方式是什么呢
execfile /产卵
喜欢产卵和采取额外execfile数组参数,没有参数,可以在shell环境下执行其他命令,不要运行额外的命令。
让我们用execfile和产卵
修改前面的例子中看到的系统调用是不同的,为什么它不容易注入命令。
child_process.execfile
复制代码代码如下所示:
无功child_process =需要('child_process);
var路径
child_process.execfile( /斌/ ls,{L,路径},功能(呃,结果){
console.log(结果)
});
运行系统调用
复制代码代码如下所示:
{ 25565 } execve(PID /斌/ LS
child_process.spawn
菌种更替的例子非常相似。
复制代码代码如下所示:
无功child_process =需要('child_process);
var路径
VaR LS = child_process.spawn( /斌/ ls,{L,路径})
Ls.stdout.on(数据功能(数据){
console.log(data.tostring());
});
运行系统调用
复制代码代码如下所示:
{ 26883 } execve(PID /斌/ LS
使用菌种或execfile时,我们的目标是只有一个命令执行(参数)。这意味着用户不能运行注入的命令,因为 /斌/ LS不知道如何处理反引号或管或;, /斌/ bash将解释这些命令的参数。它类似于将参数传递到SQL
查询(参数),如果你熟悉它。
但需要提醒,产卵或execfile的使用并不总是安全的。比如,跑步 /斌/找到并通过用户输入的参数可以使系统被困。find命令有一些
选项,允许你读/写任何
文件。
所以,有一些指导方针在Node.js运行系统命令:
避免使用child_process.exec,记住当你需要的参数,包括用户输入。
尽量避免让用户传递参数,使用选项比允许用户直接输入字符串要好得多。
如果您必须允许用户输入参数,请
参考该命令的参数,确定哪些选项是安全的,并建立一个白名单。