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


Posted in Javascript onDecember 05, 2014

在这篇文章中,我们将学习正确使用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,当需要包含用户输入的参数时更是如此,请牢记。
尽量避免让用户传入参数,使用选择项比让用户直接输入字符串要好得多。
如果你必须允许用户输入参数,请广泛参考该命令的参数,确定哪些选项是安全的,并建立一个白名单。

Javascript 相关文章推荐
javascript 常用方法总结
Jun 03 Javascript
jQuery EasyUI API 中文文档 - ValidateBox验证框
Oct 06 Javascript
JavaScript中获取样式的原生方法小结
Oct 08 Javascript
javascript常用函数归纳整理
Oct 31 Javascript
jquery对象和DOM对象的任意相互转换
Feb 21 Javascript
JS中将多个逗号替换为一个逗号的实现代码
Jun 23 Javascript
利用jsonp与代理服务器方案解决跨域问题
Sep 14 Javascript
Angular2管道Pipe及自定义管道格式数据用法实例分析
Nov 29 Javascript
js实现以最简单的方式将数组元素添加到对象中的方法
Dec 20 Javascript
JavaScript new对象的四个过程实例浅析
Jul 31 Javascript
详解关于element el-button使用$attrs的一个注意要点
Nov 09 Javascript
vue本地打开build后生成的dist文件夹index.html问题
Sep 04 Javascript
jQuery前端框架easyui使用Dialog时bug处理
Dec 05 #Javascript
Javascript实现获取窗口的大小和位置代码分享
Dec 04 #Javascript
Javascript 中创建自定义对象的方法汇总
Dec 04 #Javascript
dreamweaver 8实现Jquery自动提示
Dec 04 #Javascript
jquery实现动态画圆
Dec 04 #Javascript
javascript数组遍历for与for in区别详解
Dec 04 #Javascript
c#+jquery实现获取radio和checkbox的值
Sep 12 #Javascript
You might like
echo, print, printf 和 sprintf 区别
2006/12/06 PHP
PHP 的 __FILE__ 常量
2007/01/15 PHP
php中将数组存到文件里的实现代码
2012/01/19 PHP
解析php做推送服务端实现ios消息推送
2013/07/01 PHP
php结合ajax实现赞、顶、踩功能实例
2014/05/12 PHP
PHP脚本监控Nginx 502错误并自动重启php-fpm
2015/05/13 PHP
人脸识别测颜值、测脸龄、测相似度微信接口
2016/04/07 PHP
php基于PDO连接MSSQL示例DEMO
2016/07/13 PHP
PHP基于关联数组20行代码搞定约瑟夫问题示例
2017/11/07 PHP
javascript编程起步(第四课)
2007/02/27 Javascript
JavaScript 字符串与数组转换函数[不用split与join]
2009/12/13 Javascript
简短几句 通俗解释javascript的闭包
2011/01/17 Javascript
精通Javascript系列之数据类型 字符串
2011/06/08 Javascript
jquery css 设置table的奇偶行背景色示例
2014/06/03 Javascript
php,js,css字符串截取的办法集锦
2014/09/26 Javascript
JS+CSS实现弹出全屏灰黑色透明遮罩效果的方法
2014/12/20 Javascript
js实现简单的可切换选项卡效果
2015/04/10 Javascript
WEB前端实现裁剪上传图片功能
2016/10/17 Javascript
jQuery+pjax简单示例汇总
2017/04/21 jQuery
jQuery实现web页面樱花坠落的特效
2017/06/01 jQuery
vue+axios+element ui 实现全局loading加载示例
2018/09/11 Javascript
如何让node运行es6模块文件及其原理详解
2018/12/11 Javascript
使用webpack4编译并压缩ES6代码的方法示例
2019/04/24 Javascript
node事件循环和process模块实例分析
2020/02/14 Javascript
JavaScript实现猜数字游戏
2020/05/20 Javascript
使用vue引入maptalks地图及聚合效果的实现
2020/08/10 Javascript
详解python 字符串和日期之间转换 StringAndDate
2017/05/04 Python
django自带serializers序列化返回指定字段的方法
2019/08/21 Python
澳大利亚顶级美发和美容贸易超市:glamaCo
2020/01/19 全球购物
如何实现jdbc性能优化
2012/07/30 面试题
党的群众路线教育实践活动先进个人材料
2014/12/24 职场文书
大学生学年个人总结
2015/02/15 职场文书
幼儿园亲子活动通知
2015/04/24 职场文书
2015年卫生院健康教育工作总结
2015/07/24 职场文书
幼儿园小班教师随笔
2015/08/14 职场文书
JS前端可视化canvas动画原理及其推导实现
2022/08/05 Javascript