freeBuf
主站

分类

漏洞 工具 极客 Web安全 系统安全 网络安全 无线安全 设备/客户端安全 数据安全 安全管理 企业安全 工控安全

特色

头条 人物志 活动 视频 观点 招聘 报告 资讯 区块链安全 标准与合规 容器安全 公开课

官方公众号企业安全新浪微博

FreeBuf.COM网络安全行业门户,每日发布专业的安全资讯、技术剖析。

FreeBuf+小程序

FreeBuf+小程序

深度洞察 |关于JavaScript开源生态中安全漏洞传播及其演变分析
2022-05-02 17:24:52
所属地 上海

本文主要介绍Scantist科研团队近期在软件工程顶会International Conference on Software Engineering(CSE)2022中接收的一篇关于 JavaScript包管理器NPM生态中软件安全漏洞的传播及其演变分析的工作《Demystifying the Vulnerability Propagation and Its Evolution via Dependency Trees in the NPM Ecosystem》。

此工作基于Scantist独家的开源生态数据做了一个系统化安全分析,希望给开源社区的安全治理提供更多的见解和思路。

一、研究背景及动机

随着第三方组件在软件开发过程中的广泛使用,如何妥善管理第三方组件中引入的安全漏洞所带来的安全风险,尤其在2021年12月log4j RCE漏洞和2022年3月Spring框架远程命令执行漏洞事件爆发之后,成为DevSecOps过程中广受关注的问题之一。其中,关于安全漏洞的影响传播,特别是在如NPM这种大规模使用第三方组件的软件生态中,显得尤为重要。

在已有的相关工作中,研究人员主要通过两种方式分析依赖中存在的安全漏洞对用户项目的影响。

  1. 通过直接依赖关系反向追踪含有漏洞组件的下游用户
  2. 基于依赖关系进行间接依赖的可达性分析

然而,这两种依赖关系均忽视了NPM生态中软件包安装过程中上下文环境对依赖版本选择的影响,从而无法精准地得到安全漏洞在生态中真实的影响范围。

如下图所示,直接以间接依赖的可达性分析,则存在A@1.0.0->C@1.0.0->D@1.2.0->E@1.0.0的间接依赖链 ,如图(b)。

而根据NPM的依赖解析规则,由于A@1.0.0的直接依赖中已经解析并选择了D@1.0.0,而D@1.0.0亦满足C@1.0.0->D的依赖约束范围,此时应直接选择已有的D@1.1.0而不是重新安装D@1.2.0从而引入含有漏洞的E@1.0.0.

v2-13754e6df892e76dea8e5a1b0603c764_1440w.jpg

二、研究方法

基于此,本文旨在提出一种轻量且能够对安全漏洞影响尽可能准确分析的方法,对NPM生态中存在的安全漏洞进行经验研究。

v2-939b84339d3a6d790ca6d7b41f19ed0b_1440w.jpg

如上图所示,我们首先设计并实现一整套数据处理平台,对NPM生态中软件包元数据、相关漏洞数据等进行收集、整合,并自动生成并更新一个基于neo4j的图数据库 (DVGraph)。

下图为数据收集处理平台的基本架构:

v2-4d14602e33ff8bfd99eeef66c32a1b31_1440w.jpg

截止到生成经验研究所用的数据库(2019年12月),DVGraph包含114w library,1,094w version,及815个标记好的CVE漏洞,该数据库的存储空间超过15GB。

在此基础上,为了提升依赖解析的速度,我们基于对NPM中软件安装过程的分析,提出一个基于DVGraph模拟安装过程中依赖解析策略的算法(DTResolver),DTResolver能够在对任意数据软件包依赖解析的过程中,识别并找出所有依赖中含有安全漏洞的组件及相应的依赖引入路径。

v2-8e6f9ee168c6ad67dfa7d706c34980a1_1440w.jpg

此外由于NPM中广泛使用依赖约束条件(版本范围)而不是固定版本进行依赖定义,导致依赖安装结果随着时间可能发生变化

如下图中,在B@1.0.1发布后,A@1.0.0的安装过程中,对B的依赖将解析成新发布的版本而不是原有的B@1.0.0, 图中C@1.0.1的发布亦是如此。因此我们在DTResolver的基础上进一步增加了时间约束,使其能够支持在给定项目从其发布前到DVGraph更新时间内任意时刻的依赖树模拟解析。

v2-7f542698aa249741face9abbe34a6427_1440w.jpg

通过在大规模数据集(10w library version)上与现有依赖解析工具(npm-remote-ls)的对比验证,DTResolver能够完全正确地解析超过90%的依赖树,并正确识别98.1%的依赖树中存在的安全漏洞及92.6%的安全漏洞的引入路径。

三、经验研究

我们从以下两个方面分析NPM中安全漏洞的影响:

  • 安全漏洞是如何通过依赖树影响并传播到整个NPM生态的
  • 安全漏洞在依赖树中的影响是如何随着时间变化的

(一)安全漏洞影响传播分析

我们通过对DVGraph中所有的library及其version (超一千万)的依赖树进行解析并分析,发现:

  • 24.78%的包版本(271w library version)的依赖树中至少存在一个含有安全漏洞的组件,这些包版本来自19.96%的第三方组件包 (22.9w library)。
  • 16.17%的第三方组件包(18.6w library)的最新版本的依赖树中存在至少一个含有安全漏洞的组件。
  • 超过100个含有安全漏洞的组件的最新版本仍然受安全漏洞所影响。
  • 我们发现了25个安全漏洞实际上影响了超过1w个第三方组件包或10w个版本(影响大约1%的生态)。
  • 平均依赖树中每个安全漏洞会通过8条不同的依赖链影响根节点组件。
  • 在受影响的271w个包版本中,超过30%包版本的直接依赖中即存在安全漏洞。
  • 安全漏洞的传播链路大都通过有限的直接依赖影响根节点组件,78.94%的受影响组件(214w)的依赖树中,安全漏洞仅通过不超过3个直接依赖影响根节点项目。

(二)安全漏洞影响传播的演进

由于NPM中组件包更新频繁且依赖复杂,任一组件依赖树随着时间的变化也相当频繁,我们从DTResolver的验证数据集中抽取了5.4w个包版本,进而分析其从发布时间开始到2019年底的依赖树变化,并分析其中安全漏洞影响传播的变化,我们发现:

v2-0675bbc00dc84e5a023de6e57ba3ecff_1440w.jpg

  • 随着时间的发展,越来越多的包版本的依赖树中逐渐出现安全漏洞,且其中每个包版本依赖树中安全漏洞的数量也在逐渐增加。
    • 其中19.2%的包版本在其发布时依赖树中就已经存在了安全漏洞,而在分析截止时间,该数据变成了33.8%。
    • 在所有依赖树中曾经出现安全漏洞的包版本中,69.8%的包版本在截止时间的依赖树中存在的安全漏洞数量超过了发布时间,而相反情况的只有7.4。
  • 绝大部分依赖树中引入的安全漏洞(93%)是在安全漏洞被发布前就已经存在于依赖树中,而88%的安全漏洞修复版本的发布也是在漏洞发布前。
  • 随着时间的变化,依赖树中60%的安全漏洞在依赖树的动态变化过程中可以逐渐被清除,剩余40%的安全漏洞在实验截止时仍存在依赖树中。此外,这些被清除的安全漏洞在依赖树中仍然存在了371天。
  • 不及时的包版本维护(维护者)及不合理的版本约束范围(使用者)是导致大部分漏洞无法随着依赖树动态变化而自动清除的原因,需要更多的措施和工具来辅助改善生态中不同角色的不合理操作。

(三)应用示例:DTReme

基于我们经验研究的发现,我们结合DTResolver提出一种遍历依赖树解空间从而尽可能修复依赖中存在的安全漏洞的工具DTReme,在DTResolver模拟解析依赖树的过程中:

  • 向前检测:在每次解析依赖关系时,只允许解析到安全版本;
  • 向后回溯:在每次发现无法解析到安全版本时,回退到上一个节点重新选择版本。

v2-d245773415039656253f1bbb37ed0537_1440w.jpg

基于此,理论上可以遍历整个依赖树的解空间并生成包含安全漏洞最少的依赖树。通过与NPM官方的auditing工具(npm audit fix)对比,我们发现DTReme能够修复更多的安全漏洞。但同时也证明了,依赖树中相当一部分的安全漏洞无法通过版本上的调整清除,这也进一步说明了软件供应链中安全漏洞的修复与治理需要生态中各方的共同努力。

四、一些建议

基于以上发现,我们进一步针对供应链中不同参与者提出了一些可行的建议:

  • 维护者(Provider):
    • 当安全漏洞出现时,尽可能早地发布修复版本;
    • 在NPM registry中尽快deprecate含有已知安全漏洞的版本
    • 针对该组件主流使用的依赖约束,尽可能保证满足这些约束的最高版本是安全的,尤其是在推进到下一个大版本之后;
    • 尽可能频繁地检测自己维护组件的依赖中是否存在安全漏洞,以免下游用户受到影响。
  • 使用者(Consumer):
    • 将依赖锁(dependency lock, i.e., package-lock.json)和周期性依赖更新相结合,以降低完全不更新依赖带来的安全风险和频繁更新带来的兼容性问题;
    • 提高对依赖中存在的安全漏洞的防范意识,尤其是直接依赖中;
    • 采用第三方检测工具,在开发运维的过程中,时刻监控依赖中的安全漏洞。
  • 第三方检测机构(Third-party Auditor):
    • 提供更细粒度的依赖中面向安全漏洞的修复方案:现有的主流厂商仅采用粗粒度的修复方案,比如仅通过调整用户项目的直接依赖来规避依赖树中的安全漏洞,可采用类似DTReme的方案提升修复能力;
    • 提供更准确的安全漏洞可达性/可触发性分析:当前基于组件成分分析的漏洞检测手段中,凡是存在于依赖中的安全漏洞均会被认为存在危害,但这会引入大量的误报,需进一步过滤出真实引入危害的安全漏洞,可进一步引入动态模糊测试、静态函数调用可达性分析等技术,降低依赖树中安全漏洞在真实影响上的误报率。

五、结语

对于信息安全从业者来说,第三方组件信息、组件开源合规性以及组件依赖关系已成为安全合规检测的分析重点,同时可以借助开源软件成分分析工具SCA获得第三方库列表,快速并准确地识别未知文件的功能以及组件引入的安全漏洞。若想从根本上理解和解决安全问题,我们还需要对开源生态有更深入的理解。本文就是从JavaScript的开源生态做的一个系统化尝试和输出,我们也将通过开发可持续性的差异化产品功能来满足企业的多样化需求。

大型项目中经常会出现成百上千的依赖关系(组件所引用的组件)或是组件,在这种情况下,要将风险可视化并确定问题的根本原因将变得极其困难。Scantist把本文中的开源生态数据用来更准确的分析开源组件的依赖关系,通过创建依赖关系图(如下图),把项目中的复杂依赖关系和组件以图形方式呈现出来,让分析过程更清晰,让用户更加直观的了解项目中的依赖关系及组件。

v2-25cea7f13f02c43e3d2c38ea56fc3d4f_1440w.jpg探方SCA依赖关系图

如需了解更多产品与分析详情,请点击http://Scantist.io或左下方“阅读原文”,Scantist技术团队将在第一时间为您答疑解惑。

文章来源:

关于Scantist

Scantist是从新加坡南洋理工大学孵化出来的一个专注于软件漏洞检测和管理的网络安全公司。其核心产品是一套全方位软件安全分析(SaaS)平台,利用智能漏洞分析引擎确定代码库中的漏洞信息,并提供漏洞修复补丁和建议。

备注:Scantist拥有对此文章的修改和解释权。如欲转载或传播此文章,必须保证此文章的完整性,包括版权声明等全部内容。未经Scantist允许,不得任意修改或者增减此文章内容,不得以任何方式将其用于商业目的。

# 网络安全 # 漏洞分析 # 漏洞管理 # npm # 软件成分分析
本文为 独立观点,未经允许不得转载,授权请联系FreeBuf客服小蜜蜂,微信:freebee2022
被以下专辑收录,发现更多精彩内容
+ 收入我的专辑
+ 加入我的收藏
相关推荐
  • 0 文章数
  • 0 关注者
文章目录