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 相关文章推荐
JQuery Ajax通过Handler访问外部XML数据的代码
Jun 01 Javascript
javascript中callee与caller的用法和应用场景
Dec 08 Javascript
js jquery分别实现动态的文件上传操作按钮的添加和删除
Jan 13 Javascript
Javascript判断图片尺寸大小实例分析
Jun 16 Javascript
jQuery实现拖动调整表格单元格大小的代码实例
Jan 13 Javascript
js给selected添加options的方法
May 06 Javascript
基于jQuery实现弹幕APP
Feb 10 Javascript
原生JS实现层叠轮播图
May 17 Javascript
JS原生带小白点轮播图实例讲解
Jul 22 Javascript
vue组件实现进度条效果
Jun 06 Javascript
详解JavaScript事件循环机制
Sep 07 Javascript
javascript实现雪花飘落效果
Aug 19 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
Trying to clone an uncloneable object of class Imagic的解决方法
2012/01/11 PHP
thinkphp3.2.2前后台公用类架构问题分析
2014/11/25 PHP
PHP多文件上传类实例
2015/03/07 PHP
php中mysql操作buffer用法详解
2015/03/19 PHP
PHP实现的多维数组去重操作示例
2018/07/21 PHP
一个判断email合法性的函数[非正则]
2008/12/09 Javascript
JavaScript 继承详解 第一篇
2009/08/30 Javascript
jQuery对表单的操作代码集合
2011/04/06 Javascript
File, FileReader 和 Ajax 文件上传实例分析(php)
2011/04/27 Javascript
Javascript中找到子元素在父元素内相对位置的代码
2012/07/21 Javascript
按下回车键指向下一个位置的一个函数代码
2014/03/10 Javascript
javascript表单验证大全
2015/08/12 Javascript
JS实现三个层重叠点击互相切换的方法
2015/10/06 Javascript
基于React.js实现原生js拖拽效果引发的思考
2016/03/30 Javascript
vue实现提示保存后退出的方法
2018/03/15 Javascript
基于Vue2实现简易的省市区县三级联动组件效果
2018/11/05 Javascript
layui的layedit富文本赋值方法
2019/09/18 Javascript
微信小程序监听用户登录事件的实现方法
2019/11/11 Javascript
vue过滤器实现日期格式化的案例分析
2020/07/02 Javascript
深入了解JavaScript词法作用域
2020/07/29 Javascript
使用Python中的线程进行网络编程的入门教程
2015/04/15 Python
python制作企业邮箱的爆破脚本
2016/10/05 Python
python中lambda()的用法
2017/11/16 Python
python tkinter canvas 显示图片的示例
2019/06/13 Python
如何使用django的MTV开发模式返回一个网页
2019/07/22 Python
Python中猜拳游戏与猜筛子游戏的实现方法
2020/09/04 Python
Erwin Müller穆勒家居瑞士官网:您整个家庭的邮购公司
2019/12/28 全球购物
俄罗斯连接商品和买家的在线平台:goods.ru
2020/11/30 全球购物
房地产出纳岗位职责
2013/12/01 职场文书
人事部主管岗位职责
2013/12/26 职场文书
工程造价专业大学生职业生涯规划书
2014/01/18 职场文书
老师对学生的寄语
2014/04/09 职场文书
师恩难忘教学反思
2014/04/27 职场文书
检讨书模板大全
2015/05/07 职场文书
golang正则之命名分组方式
2021/04/25 Golang
Python 读写 Matlab Mat 格式数据的操作
2021/05/19 Python