原文标题:Mininode: Reducing the Attack Surface of Node.js Applications
原文作者:Igibek Koishybayev, Alexandros Kapravelos
原文链接:https://www.usenix.org/system/files/raid20-koishybayev.pdf
发表会议:RAID’20
笔记作者:NING@SecQuan
笔记小编:ourren@SecQuan
1 研究介绍
JavaScript 作为一种编程语言,它几乎成为了 Web 前端开发的默认语言,受到开发者的青睐。而 NodeJS 更是支持 JavaScript 完成服务端的工作。然而随着开发的深入,第三方包的应用必不可少,而在开发时,开发人员必然会存在冗余的包引入,这些冗余的方法将会导致攻击面的扩大,因此减少这些膨胀的代码块十分重要。
本文的主要贡献在于以下三点:
-
开发了一个系统,它可以通过减少未使用的代码,从而降低程序的攻击面。
-
分析了 67 万的 NodeJS 程序,发现 11 万(11.3 %)的程序都会依赖一些有漏洞的第三方包。
-
限制一些内置模块(fs, net)的过高权限。
2 主要架构
该系统架构如图 1 所示。主要包括五个部分,这里主要叙述其主要功能。
Parser
通过原生模块 esprima 构建抽象语法树 AST,用于表示代码结构。
Value-binding
主要是将一些变量、方法的别名与原内容进行绑定,从而避免因名称不同导致歧义和无法解析的情况。
Load Dependency Builder
主要是构建文件级别的依赖图。首先寻找文件入口,接着根据不同文件之间的 Require 关系(来源于 AST 的解析),构建起文件之间的依赖图。这一步主要是从文件的粒度上删减不必要的内容。
Call Graph Builder
这一步则是上一步的细化,这里将从方法(代码层面)的粒度上,同时依赖 AST 完成对未使用方法的标记,以便完成标记工作。
Reducer
根据 AST 和之前标注的信息,完成 AST 的裁剪,并最终生成更新的代码。
3 细节处理
由于 JS 代码的灵活性和动态特性,在整个流程中必然会面对许多挑战。论文中详细解释了他们面对的问题和解决方法,这里主要讲一下可能大多数人可能没有考虑到的几个问题。
Re-export
在 CommonJS 模块系统中,可以通过重新导出模块并添加其他功能来扩展其他模块。例如,这里在 request-v2.js 文件中,他扩展了 request.js 中的 patch 方法。而在 index.js 中,模型应该将 get 方法识别为 request.js ,从而避免裁剪掉该文件。
Cross-reference
如图 3 所示,这里 foo.js 和 index.js 都引用了 bar.js 模块。那么理论上应该保留 bar.js 的全部代码,因为 export.w 被 foo.js 引用,export.z 被 index.js 引用,但是实际上,从入口文件来看,index.js 的执行流程中,并不会使用到 export.w 因此这部分代码理应被删除。
4 部分实验结果
Mininode Reduction Validation
可以看到,整体的测试效果不错。删除不必要的模型数目很多,但的确会存在过度修剪得情况,导致代码存在测试失败的情况,这是后期可以研究的问题。
Attack Surface Reduction
在整个 NPM 中选取了大批量的数据进行测试发现,数据分布情况与验证集近似,但由此可以看出 NPM 系统中确实存在着较多的危险攻击面,这是值得注意的。
5 个人思考
-
Bloated code 问题随着代码量的增大,是必然会存在的一个问题,目前针对 js 的研究也有一些文章。而本文在这些研究中,针对一些细节问题进行了一些研究和描述,这是部分文章中没提及的。
-
此外本文在方法论的介绍之外,也对大体量的代码进行了调研工作,具有一定的现实评估价值。但模型存在一定的过度缩减问题,这个可以在对样本的研究后,进一步提升模型的成功率。
安全学术圈招募队友-ing
有兴趣加入学术圈的请联系 secdr#qq.com
原文始发于微信公众号(安全学术圈):Mininode:减少NodeJS程序攻击面