原文标题:Slimming javascript applications: An approach for removing unused functions from javascript libraries

原文作者:H.C. Vázquez, A. Bergel, S. Vidal, J.A. Díaz Pace, C. Marcos

原文链接:https://www.sciencedirect.com/science/article/pii/S0950584918302210

发表会议:IST"19

笔记作者:NING@SecQuan

笔记小编:ourren@SecQuan

1 研究介绍

Javascript 应用程序发布时,通常会出现程序与所用库进行捆绑部署,例如当网站存在 Chart.js 制作的嵌入图表时,该网站会包含一个大型的 Chart.budle.js 文件,其是由 Chart.js 及其所使用三方库的源代码构成的,因此这样会导致整个应用的大小、性能受到限制。

本文的目标就是对去除这些依赖项中不必要的源代码(UFF,unused Foreign Function),从而缩小程序大小。具体开发了一种名为UFF Remover 的工具。

2 主要架构

图 1 UFF 处理流程

Identification

首先使用Browserify 捆绑工具去遍历模块之间的依赖关系,从而构建依赖图,并将没有边的模块在图中进行标记,而存在连接的其他节点构成下一阶段的输入。

Instrumentation

这里通过对 JS 文件解析,进而识别所有函数(这里针对函数声明和函数表达式),并在识别的所有函数前加一条指令,要求指令执行时,将函数是否执行进行记录,从而获取所有需要的函数。

Dynamic Detection

动态运行时,将会吧第二步中所有的内容输出列表 UFF,并提供给开发人员确认。

Removal

当 UFF 被发现并被开发人员确认后,便需要删除,而由于存在动态加载的方式,那么必然会存在误报,这里作者的做法的是“清空” 而不是“删除” 函数。通过引入XMLHttpRequest,当出现误报时,该函数便会从服务器进行加载。但该方法会存在缺点就是需要添加代码和全局变量,同时会延迟加载。

3 实验效果

实验选择了 22 多个流行 JavaScript 应用程序进行测试,要求其满足以下条件:

  • 开源

  • 可以运行在 Web 浏览器中

  • 至少依赖一个库

  • 拥有编译和测试信息

  • 应用程序功能覆盖率大于 85%(方便函数追踪,需要程序附带的单元测试)

表 1 实验使用的应用 表 2 UFF的识别和去除

RQ:JS 应用的 UFF 数目如何?去除可以缩减多少源代码?

表 2 展示了本次实验发现、去除、清空的 UFF 数目。可以发现本次针对这些项目共去除了 7021 个 UFF。其中 30.5% (2142) 被完全去除、69.5% (4879) 被清空。然而在整个实验中发现几乎在包中使用的函数,一半来源于依赖的第三方包,函数总数 19,586,其中 10,063 (51.38%) 属于库;同时 bundle LOC(line of code)总数为 336,983,其中 158,695 (47.09%) 属于依赖库。因此分析属于依赖库的函数以删除不需要的函数很重要。

图 2 UFF 识别和去除结果

同时图 2 显示了 UFF 识别数目占功能总数的百分比。中位数为 27.56%。UFF 消除数目占功能总数的百分比。中位数为 17.99%。

4 个人思考

  • 删减不必要的打包代码是很重要的,能够缩减下载时间,同时可能加快网页端的加载。同时这篇文章所使用的 “清空” 是一个较为聪明的手段,能够帮助代码尽可能地运行起来,而不会缺少部分所需函数。

  • 该篇文章应该是 Bloated code 在 JS 服务端代码的早期工作,具有一定的开创意义,同时推动了后面许多文章的前进,包括安全领域、软件工程领域等。

  • 该篇文章缺少一些细节描述,支持 ES6 规范,但是可能在一些特殊情况下无法识别 UFF,需要依赖与测试用例来遍历所有功能,同时动态的使用可能会导致一定的效率问题。

安全学术圈招募队友-ing

有兴趣加入学术圈的请联系secdr#qq.com

声明:本文来自安全学术圈,版权归作者所有。文章内容仅代表作者独立观点,不代表安全内参立场,转载目的在于传递更多信息。如有侵权,请联系 anquanneican@163.com。