软件供应链管理公司Sonatype最近发布的调研报告显示,过去一年里,涉恶意第三方组件的供应链攻击事件增长了633%,已知实例超过8.8万例。同时,软件组件从自身依赖项继承可传递漏洞的实例也达到了前所未有的水平,三分之二的开源库都惨遭荼毒。
Sonatype在其最近发布的《软件供应链状况》报告中写道:“依赖项的网络化性质凸显了全面了解这些复杂供应链的重要性。依赖项会影响我们的软件,所以了解依赖项的源头是漏洞响应的关键。很多企业并不具备所需的可见性,所以才会在2022年夏天都过去很久的时候仍在继续他们的Log4Shell事件响应流程。”
Log4Shell是2021年11月发现的Log4j开源Java库严重漏洞,该库广泛应用于用户登录,通常作为直接依赖项捆绑在数百万个企业应用程序和软件产品中。Sonatype的监测显示,2022年8月,绑定版Log4j的采用率在65%左右。更糟的是,这还是没考虑到Log4Shell漏洞源自Log4j-core中Java类JndiManager的情况,而JndiManager已被另外783个项目引入,现存于1.9万多个软件组件中。
Log4Shell就好像分水岭,昭示着作为现代软件开发基础的开源软件生态中存在的固有风险,以及恰当管理此类风险的必要性。该漏洞也促使私营企业、软件存储库管理方、Linux基金会和政府机构展开多个计划,意图保护软件供应链安全。然而,在开源供应链管理方面,大多数组织都远未达到所需的要求。
开源消费持续增长
Maven Central(Java)、npm(JavaScript)、PyPi(Python)和NuGet(.NET)这四个顶级组件存储库的包下载量年均复合增长率为33%。这一增长率不及往年,比如2021年的增长率就高达73%,但组件下载量已经超过了2021年所有存储库的下载量,总计达3万亿次以上。仅npm这一个存储库今年的下载量就会超过全部四个存储库在2021年的下载量。
开源消费率的下降未必是由于用户实施了更严格的开源采购和管理策略,普遍是考虑到各个编程语言生态系统已经达到的规模和它们添加新项目及发布的速度。
“尽管增长速度正在放慢,但增长的绝对规模仍在复合之前的年增长率。”Sonatype总结道,“开源采用的速度没有显示出任何将会很快失去动力的迹象。”
供应链攻击类型多样化
到去年年底,Sonatype已追踪到大约1.2万起已知恶意供应链攻击实例,但这一数字如今已增加至8.8万多起,同比增长633%。该公司还发现了9.7334万个以多种方式分发的恶意软件包。
恶意软件包增长的主要原因之一是名为“依赖混淆”的攻击技术,这种技术自2021年2月安全研究人员公开披露之后就普及了。该技术利用了大多数软件包管理客户端配置成同时在公共社区存储库和内部存储库搜索软件包的行为。
如果两个搜索路径中都出现了软件包名称,软件包管理客户端就会获取版本号较高的那个包。这就导致了一个问题:很多企业使用内部开发的软件包,这些包仅存在于内部存储库中,且从未打算公开发布。然而,只要攻击者从清单文件中找到这些包的名称,他们就可以在公共存储库中发布具有更高版本号的同名恶意包,欺骗软件构建客户端。
很难说是否所有的依赖混淆攻击都是恶意的,因为渗透测试人员也经常使用这种技术。不过,企业可以在公共存储库中注册私有包的名称,或者为所有包加上可后续注册为公共存储库上的命名空间或作用域的前缀(意味着攻击者不再能够发布带有这些前缀的包),从而保护自身。
早已为人所知的其他几类大规模攻击方式还有误植域名和品牌劫持。误植域名是一种被动攻击方式,指的是攻击者故意注册名称类似流行软件包的恶意包,期待开发人员在构建脚本或构建命令中输错包名称。
品牌劫持与之类似,但针对的是其他软件包维护者,寄希望于他们将被劫持或误植的包作为依赖项纳入自己的组件中。如果合法包的维护者将所有权传给其他人,或者停止开发并删除该包而空出此包的旧名称,也可能会发生这种情况。
恶意代码注入是另一种攻击者更爱用的技术:攻击者入侵开发人员的系统或代码存储库,悄悄将恶意代码注入到开发人员的包中。软件包维护者如果将代码存储库提交权限授予多方,而这些人带有恶意或被黑,也会发生恶意代码注入的情况。
还有一种攻击类型与恶意代码注入十分相似,但是合法开发人员所为,名为抗议软件。这种攻击中,开发人员将恶意代码添加到自己以前干净的包中,作为抗议的标志。
选择安全实践良好的组件
构建和维护所有内部软件开发工作所用组件的清单,跟踪这些组件中发现的漏洞,是缓解安全风险的一个重要方面。但是,设置明确的组件溯源策略同样重要。选择自身代码漏洞发生率低的组件或库并不能保证安全,因为很多组件或库都会从自己的依赖项继承漏洞。所以,这些组件或库响应继承漏洞并更新自身依赖项所需的时间就非常关键了。
Sonatype分析了1.2万多个企业应用中常用的库,发现其中仅10%的库在代码中直接存在漏洞。然而,一考虑从依赖项和这些依赖项的依赖项中继承来的可传递漏洞,漏洞发生率就飙升到了62%。平均而言,每个库都有5.7个依赖项。
此外,长远角度看,选择低漏洞发生率的组件也未必会带来更好的安全结果,因为研究人员在如何选择想要审查的项目方面存在很多偏好。换句话说,常用项目看起来漏洞更多,可能仅仅是因为盯着这些项目的人也更多。
“由于大多数漏洞源自可传递依赖项,最清晰明确的建议就是仔细考虑你用的每个库。”Sonatype研究人员说道,“偏向依赖树更小的库。寻找依赖项发布新版本时快速更新(MTTU(平均更新时间)短)的项目。最小化依赖项总数,并将自身项目依赖项的更新时间维持在较短水平,是减少可传递漏洞风险的两个关键因素。”
有几个指标可以用来判断开源项目的安全实践水平。其中之一是开源安全基金会(OpenSSF)开发的Security Scorecard(安全记分卡)系统。该系统执行一系列自动化检查,检查开源项目是否具有未修复漏洞,是否使用工具辅助更新其依赖项,是否进行持续集成(CI)测试,是否执行自动化代码模糊测试,是否使用静态代码分析工具,是否规避危险编码操作,是否在合并新代码之前执行代码审查,是否声明并固定依赖项,等等。
Sonatype采用自己的数据评估上述实践对降低项目漏洞发生率有多大影响,结果发现影响最大的几个安全实践是代码审查、不引入二进制工件、避免危险编码操作(分支保护)、固定依赖项,以及审核代码提交。
“我们建议开发人员按顺序考量MTTU、Security Scorecard、OpenSSF Criticality和SourceRank,选择得分最高的组件。”Sonatype研究人员表示,“我们理解综合评估各种得分可能会很难。所以,我们在公开漏洞数据库OSS Index中加入了新的Sonatype Safety Rating,希望能帮助降低这一难度。”
企业对自身开源实践过于自信
Sonatype访问调查了662位企业工程专业人员,就开源组件使用、依赖项管理、治理、审批流程和工具使用情况提出了40个问题。大多数回复显露出的供应链管理水平低于在Sonatype评估中得到高质量结果所需的水平。
最高评分出现在修复和应用库存清单这两个类别。例如,68%的受访者确信自家应用没有使用已知带漏洞的库,84%的受访者宣称仔细审查了所用开源组件的安全历史。然而,这并不符合Sonatype的实际发现:扫描5.5万个随机选择的企业应用,结果显示其中68%都带有已知漏洞。
“我们运用调查中收集到的人员统计数据,按职位细分结果。”研究人员说道,“结果引人深思。目前存在着一种过于乐观的倾向:相比其他职位,经理报出的成熟度水平会更高一些。整个调查范围内,对比IT经理和信息安全领域其他职位的从业者,这种差异在统计学意义上十分显著。”
《软件供应链状况》
https://www.sonatype.com/state-of-the-software-supply-chain/introduction
参考阅读
软件供应链安全研讨会全纪实
软件供应链安全治理与运营
[调研]软件供应链安全问题触及高管层
[调研]仅3%的开源软件漏洞真的可攻击