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 相关文章推荐
Extjs4 Treegrid 使用心得分享(经验篇)
Jul 01 Javascript
node.js中的fs.utimes方法使用说明
Dec 15 Javascript
jQuery实现给页面换肤的方法
May 30 Javascript
javascript实现网页字符定位的方法
Jul 14 Javascript
JS实现超精简的链接列表在固定区域内滚动效果代码
Nov 04 Javascript
jquery实现点击其他区域时隐藏下拉div和遮罩层的方法
Dec 23 Javascript
Vue.js每天必学之指令系统与自定义指令
Sep 07 Javascript
jQuery弹出遮罩层效果完整示例
Sep 13 Javascript
JS公共小方法之判断对象是否为domElement的实例
Nov 25 Javascript
jQuery Pagination分页插件使用方法详解
Feb 28 Javascript
vue+webpack实现异步加载三种用法示例详解
Apr 24 Javascript
详解Webpack + ES6 最新环境搭建与配置
Jun 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
PHP 杂谈《重构-改善既有代码的设计》之三 重新组织数据
2012/04/09 PHP
php使用Cookie实现和用户会话的方法
2015/01/21 PHP
PHP的APC模块实现上传进度条
2015/10/27 PHP
PHP的Laravel框架结合MySQL与Redis数据库的使用部署
2016/03/21 PHP
PHP实现广度优先搜索算法(BFS,Broad First Search)详解
2017/09/16 PHP
PHP使用HTML5 FormData对象提交表单操作示例
2019/07/02 PHP
javascript验证上传文件的类型限制必须为某些格式
2013/11/14 Javascript
javascript中的__defineGetter__和__defineSetter__介绍
2014/08/15 Javascript
JavaScript实现找出字符串中第一个不重复的字符
2014/09/03 Javascript
Javascript基础知识(三)BOM,DOM总结
2014/09/29 Javascript
JavaScript实现俄罗斯方块游戏过程分析及源码分享
2015/03/23 Javascript
javascript实现倒计时(精确到秒)
2015/06/26 Javascript
AngularJS Module方法详解
2015/12/08 Javascript
Javascript将双字节字符转换成单字节字符并计算长度
2016/06/22 Javascript
使用Angular.js开发的注意事项
2016/10/19 Javascript
在网页中插入百度地图的步骤详解
2016/12/02 Javascript
for循环 + setTimeout 结合一些示例(前端面试题)
2017/08/30 Javascript
最简单的vue消息提示全局组件的方法
2019/06/16 Javascript
微信小程序Echarts图表组件使用方法详解
2019/06/25 Javascript
使用python将mdb数据库文件导入postgresql数据库示例
2014/02/17 Python
python实现字符串和字典的转换
2018/09/29 Python
Python pandas.DataFrame调整列顺序及修改index名的方法
2019/06/21 Python
在OpenCV里使用特征匹配和单映射变换的代码详解
2019/10/23 Python
Python实现检测文件的MD5值来查找重复文件案例
2020/03/12 Python
Python 实现一行输入多个数字(用空格隔开)
2020/04/29 Python
详解Python利用configparser对配置文件进行读写操作
2020/11/03 Python
HTML5 视频播放(video),JavaScript控制视频的实例代码
2018/10/08 HTML / CSS
Belle Maison倍美丛官网:日本千趣会旗下邮购网站
2016/07/22 全球购物
C语言编程练习
2012/04/02 面试题
Linux开机引导的步骤是什么
2014/02/26 面试题
中级会计职业生涯规划范文
2014/01/16 职场文书
2014年银行客户经理工作总结
2014/11/12 职场文书
2019财务转正述职报告
2019/06/27 职场文书
python四个坐标点对图片区域最小外接矩形进行裁剪
2021/06/04 Python
Python实现简单的俄罗斯方块游戏
2021/09/25 Python
python编程项目中线上问题排查与解决
2021/11/01 Python