当前位置: 首页 > 编程笔记 >

Node.js中安全调用系统命令的方法(避免注入安全漏洞)

冀耀
2023-03-14
本文向大家介绍Node.js中安全调用系统命令的方法(避免注入安全漏洞),包括了Node.js中安全调用系统命令的方法(避免注入安全漏洞)的使用技巧和注意事项,需要的朋友参考一下

在这篇文章中,我们将学习正确使用Node.js调用系统命令的方法,以避免常见的命令行注入漏洞。

我们经常使用的调用命令的方法是最简单的child_process.exec。它有很一个简单的使用模式;通过传入一段字符串命令,并把一个错误或命令处理结果回传至回调函数中。

这里是你通过child_process.exec调用系统命令一个非常典型的例子。


child_process.exec('ls', function (err, data) {

    console.log(data);

});

不过,当你需要在你调用的命令中添加一些用户输入的参数时,会发生什么?显而易见的解决方案是把用户输入直接和您的命令进行字符串合并。但是,我多年的经验告诉我:当你将连接的字符串从一个系统发送到另一个系统时,总有一天会出问题。


var path = "user input";

child_process.exec('ls -l ' + path, function (err, data) {

    console.log(data);

});

为什么连接字符串会出问题?

嗯,因为在child_process.exec引擎下,将调用执行"/bin/sh"。而不是目标程序。已发送的命令只是被传递给一个新的"/bin/ sh'进程来执行shell。 child_process.exec的名字有一定误导性 - 这是一个bash的解释器,而不是启动一个程序。这意味着,所有的shell字符可能会产生毁灭性的后果,如果直接执行用户输入的参数。


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

比如,攻击者可以使用一个分号";"来结束命令,并开始一个新的调用,他们可以使用反引号或$()来运行子命令。还有很多潜在的滥用。

那么什么是正确的调用方式?

execFile / spawn

像spawn和execFile采用一个额外的数组参数,不是一个shell环境下可以执行其他命令的参数,并不会运行额外的命令。

让我们使用的execFile和spawn修改一下之前的例子,看看系统调用有何不同,以及为什么它不容易受到命令注入。

child_process.execFile


var child_process = require('child_process');

var path = "." child_process.execFile('/bin/ls', ['-l', path], function (err, result) {     console.log(result) });


运行的系统调用

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

child_process.spawn

使用 spawn 替换的例子很相似。


var child_process = require('child_process');

var path = "." var ls = child_process.spawn('/bin/ls', ['-l', path]) ls.stdout.on('data', function (data) {     console.log(data.toString()); });

运行的系统调用


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

当使用spawn或execfile时,我们的目标是只执行一个命令(参数)。这意味着用户不能运行注入的命令,因为/bin/ls并不知道如何处理反引号或pipe或;。它的/bin/bash将要解释的是那些命令的参数。它类似于使用将参数传入SQL查询(parameter),如果你熟悉的话。

但还需要警告的是:使用spawn或execFile并不总是安全的。例如,运行 /bin/find,并传入用户输入参数仍有可能导致系统被攻陷。 find命令有一些选项,允许读/写任意文件。

所以,这里有一些关于Node.js运行系统命令的指导建议:

避免使用child_process.exec,当需要包含用户输入的参数时更是如此,请牢记。
尽量避免让用户传入参数,使用选择项比让用户直接输入字符串要好得多。
如果你必须允许用户输入参数,请广泛参考该命令的参数,确定哪些选项是安全的,并建立一个白名单。

 类似资料:
  • 运行静态扫描时,我收到一个Veracode错误:操作系统命令(“操作系统命令注入”)中使用的特殊元素的中和不当(CWE ID 78) 应用程序调用一个进程,其中包含我从前端收到的参数(应用程序在内部使用,这是一个userId)。 我如何解决这个Veracode问题?有没有“安全”的方式来运行流程?

  • Slitaz提供许多关于系统安全的信息。软件在进入稳定发行版之前会经过几个月的测试。在启动的时候,服务会由rc脚本运行。要想知道开机自启动的服务列表,你可以查阅/etc/rcS.conf中的RUN_DAEMONS变量: $ cat /etc/rcS.conf | grep RUN_DAEMONS 要显示当前进程及其PID、内存使用,你可以使用ps命令或者htop程序(需安装): $ ps $ ht

  • 我正在接管一些在PHP中使用eval()函数的webgame代码。我知道这可能是一个严重的安全问题,所以在决定是否取消这部分代码之前,我希望得到一些帮助来检查代码的参数。目前我已经从游戏中删除了这部分代码,直到我确定它是安全的,但功能的损失是不理想的。我宁愿对此进行安全保护,而不是重新设计整个段以避免使用eval(),假设这样的事情是可能的。下面是防止恶意代码注入的相关代码片段。$value是一个

  • Chapter 10. 系统安全 Table of Contents 10.1. 安全等级 10.2. 安全策略 10.3. 安全工具 系统安全是应用的基础,一个安全的系统才能长时间不间断运行,有效支持我们的应用。建立一个安全的系统需要一个好的软硬件平台,但更重要的是要有一个优秀的系统管理员能及时地发现安全问题和解决安全问题。 如何评价一个系统的安全程度,美国国家计算机安全中心(NCSC)制定了可

  • 从2.0版本开始Spring Security 改进了对服务层方法的安全支持,它提供了对JSR-250注解安全支持以及框架的原生@Secured注解的支持。从3.0开始你也可以使用新的基于表达式的注解。你可以将安全应用到单个bean.使用intercept-methods元素装饰Bean的声明。或者你可以在使用AspectJ风格的切入点应用安全到整个服务层的多个Bean类。 <global-met

  • 我有网站运行在node.js&express服务器上。我了解到该网站存在以下漏洞。 远程攻击者可以发送巧尽心思构建的HTTP请求,并强制其针对某些流量边缘模式对错误连接进行日志记录语句。这会导致并发使用内存池进行单独的连接,并引发影响。 利用HTTP报头的间隔会在服务器进程中造成溢出,从而覆盖堆栈的一部分,通过覆盖下一个操作的字节来倒回请求处理。 一旦对暴露的endpoint进行相应的精心编制;环

  • 我在mybatis查询中使用“$”表示法: order参数可以是类似于“id desc”的东西,我需要担心这里的sql注入吗?我们知道mybatis使用,如果mybatis针对“select”语句调用,或者jdbc驱动程序实现不允许在一次调用中使用多个语句,那么sql注入是不可能的,对吗? 这是否足以检查参数有sql分隔符?

  • 问题内容: 我想像这样的代码来获取有关Java7功能的详细信息 可以做这样的事情 但坦白说对我来说还不太清楚。请解释一下? 问题答案: Null-safe方法调用是针对Java 7提出的,作为Project Coin的一部分,但并未最终发布。 在此处查看所有建议的功能以及所有最终选择的功能-https: //wikis.oracle.com/display/ProjectCoin/2009Prop