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 相关文章推荐
niceTitle 基于jquery的超链接提示插件
May 31 Javascript
提高javascript效率 一次判断,而不要次次判断
Mar 30 Javascript
JS特殊函数(Function()构造函数、函数直接量)区别介绍
May 19 Javascript
jquery ajax 局部无刷新更新数据的实现案例
Feb 08 Javascript
浅谈javascript实现八大排序
Apr 27 Javascript
jquery正则表达式验证(手机号、身份证号、中文名称)
Dec 31 Javascript
Javascript中prototype的使用详解
Jun 18 Javascript
详谈Ajax请求中的async:false/true的作用(ajax 在外部调用问题)
Feb 10 Javascript
详解Angular-Cli中引用第三方库
May 21 Javascript
three.js着色器材质的内置变量示例详解
Aug 16 Javascript
JavaScript实现简单验证码
Aug 24 Javascript
区分vue-router的hash和history模式
Oct 03 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数组函数序列之array_key_exists() - 查找数组键名是否存在
2011/10/29 PHP
洪恩在线成语词典小偷程序php版
2012/04/20 PHP
php使用GD创建保持宽高比缩略图的方法
2015/04/17 PHP
用倒置滤镜把div倒置,再把table倒置。
2007/07/31 Javascript
JavaScrip单线程引擎工作原理分析
2010/09/04 Javascript
Uglifyjs(JS代码优化工具)入门 安装使用
2020/04/13 Javascript
jquery动画2.元素坐标动画效果(创建一个图片走廊)
2012/08/24 Javascript
IE下使用cloneNode注意事项分享
2012/11/22 Javascript
jQuery中innerWidth()方法用法实例
2015/01/19 Javascript
js获取json元素数量的方法
2015/01/27 Javascript
js实现简单鼠标跟随效果的方法
2015/04/10 Javascript
javascript制作幻灯片(360度全景图片)
2015/07/28 Javascript
JQuery 设置checkbox值二次无效的解决方法
2016/07/22 Javascript
bootstrap weebox 支持ajax的模态弹出框
2017/02/23 Javascript
jQuery plugin animsition使用小结
2017/09/14 jQuery
node.js通过axios实现网络请求的方法
2018/03/05 Javascript
vue.js打包之后可能会遇到的坑!
2018/06/03 Javascript
vue+axios+promise实际开发用法详解
2018/10/15 Javascript
使用JS来动态操作css的几种方法
2019/12/18 Javascript
Vant picker 多级联动操作
2020/11/02 Javascript
element el-table表格的二次封装实现(附表格高度自适应)
2021/01/19 Javascript
tornado框架blog模块分析与使用
2013/11/21 Python
Python查找第n个子串的技巧分享
2018/06/27 Python
ubuntu16.04制作vim和python3的开发环境
2018/09/23 Python
python opencv 简单阈值算法的实现
2019/08/04 Python
python实现凯撒密码、凯撒加解密算法
2020/06/11 Python
在pycharm中文件取消用 pytest模式打开的操作
2020/09/01 Python
CSS3中Animation属性的使用详解
2015/08/06 HTML / CSS
CSS3实现点击放大的动画实例代码
2017/02/27 HTML / CSS
YesStyle美国/全球:购买亚洲时装、美容化妆品和生活百货
2017/01/16 全球购物
列车长先进事迹材料
2014/01/25 职场文书
争先创优心得体会
2014/09/12 职场文书
党员批评与自我批评发言稿
2014/10/14 职场文书
php远程请求CURL案例(爬虫、保存登录状态)
2021/04/01 PHP
oracle索引总结
2021/09/25 Oracle
postgresql中如何执行sql文件
2023/05/08 PostgreSQL