Fifty Years of Open Source Software Supply Chain Security
开源软件供应链安全的五十年
Russ Cox
1972年3月,美国空军开始评估霍尼韦尔公司的 Multics 系统,以判断它是否适用于安全环境。
该报告于1974年中期发布,得出的结论是,尽管 Multics 不够安全,但优于同类系统,可能是构建安全系统的合理起点。
报告中提到了在一个看似无害的系统调用中加入后门(当时称为“陷阱门”)的可能性。
当系统调用接收到特定且极不可能的输入时,允许读取或写入任意内核内存字。
这个微小的修改足以彻底破坏系统安全性,报告还探讨了这种修改可能如何实现和隐藏。
2024年3月,微软的 Postgres 开发者 Andres Freund 注意到,他的 Debian Linux 系统上的 ssh 守护进程在处理网络背景攻击流量(试图暴力破解登录)时使用了异常多的 CPU。
经过深入调查,Freund 发现 Debian 系统中链接到 ssh 的压缩库 liblzma 的最新版本中含有一个专门针对 ssh 的后门。
只要传入一个特定且极不可能的输入,该 ssh 守护进程就会允许攻击者在互联网上执行任意 shell 命令。
这一微小的改动彻底破坏了最新 Debian 系统的安全性,接下来的几周里,全球的安全研究人员都在研究这种变更是如何被实施和隐藏的。
由于 liblzma 是 xz 项目的一部分,该攻击如今被广泛称为“xz 攻击”。
Understand the Software Supply Chain
理解软件供应链
要保护你的软件供应链,首先必须理解它到底是什么。
我们从定义开始:软件供应链是指所有可能发生供应链攻击或引入漏洞的环节。
而“理解”的更重要含义是:清楚地知道你自己的软件供应链到底是什么样的——这其实非常困难。
“链”这个词听起来很简单,但供应链更像是分形结构:无论你多么细致地观察,它都复杂无比。
从最低层来看,你可以观察构建一个程序所执行的命令以及命令之间的依赖关系。
这些构建图与程序本身的包依赖结构是对应的。
即使是简单程序,其构建图也可能复杂得无法打印出来。
Go 项目一直优先避免不必要的依赖,力求保持软件简洁。然而,就在我写这篇文章时,构建 go 命令仍需执行 714 个命令,构建 297 个包,生成 3,132 条依赖边。
go 命令的一个特殊之处在于它没有外部依赖:它使用的所有包都属于 Go 项目自身。
而在稍微复杂些的命令中,Kubernetes 的 kubelet 构建过程要执行 3,289 个命令,依赖 137 个 Go 模块中的 1,581 个包,许多还来自 Kubernetes 项目以外。
这些例子都是相对较小的底层工具。更高层级的程序构建复杂度更高。
在本期 acmqueue 的另一篇文章中,Josie Anugerah 和 Eve Martin-Jones 更详细地探讨了开源构建图的复杂性,并指出大多数程序都有多个可能的构建图,具体取决于其构建环境。
人们很容易以为这类依赖图就是整个软件供应链,但其实它们只是最显眼的一部分。
依赖图中的每个包或模块都可能由不同的个人或组织编写,其安全实践、代码审查标准等也各不相同。
如果能对每一个依赖的细节有更多了解自然是好事,但现实中这些信息通常不可获取,而且会随着时间变化。
另一种“图”表示的是软件在构建和分发给用户过程中所经过的各类计算机和服务。
在这些系统中任意一处进行恶意篡改都是可能的,每一处都可能成为攻击点或漏洞源。
你应该关心谁有权限访问某个依赖项目、将来可能是谁、他们使用的基础设施是什么,等等。
但大多数时候,由于缺乏可见性,这些问题被忽视了。然而它们仍然存在。
理解软件供应链对于识别哪些环节需要加固至关重要。
整个行业在这方面仍有大量工作要做,而本文接下来将转向那些已知有效的具体加固手段。
Authenticate Software
验证软件身份
Multics 评估报告考虑了在“分发阶段”插入后门的可能性,比如利用“不安全的通信方式”或通过“伪造信笺”发送恶意更新。
这些说法可能已经过时,但背后的思想依然适用。
XcodeGhost 就是这种攻击方式的现代例证。
解决这一问题可以说是现代软件供应链安全领域最接近成功的案例。
加密签名可以防止代码在签名与验证之间被恶意篡改。
唯一剩下的问题是密钥分发:验证者必须知道代码应由谁签名。
关于密钥分发问题,有很多可行的解决方案。
最简单的做法是忽略身份验证,仅记录并分发构建中使用的特定依赖版本的加密哈希值。
预先分发这些哈希值的验证方式可彻底消除下载服务器、代理和其他网络中间件作为攻击点的可能性。
Debian 的依赖打包系统包含这种检查机制,这使得 xz 攻击者无法仅仅修改已有的 xz 副本,而必须发布新版本。
这并未阻止攻击,但显著提高了攻击难度。
从更大范围看,这些哈希值不必全部预分发,而是可由一个可信数据库集中管理。
Go 校验和数据库就是该方法的真实应用示例,它保护着数百万 Go 开发者。
该数据库保存每个公共 Go 模块每个版本的 SHA256 校验和。
数据库的每条记录都由数据库服务器的私钥签名。
相应的公钥硬编码在 Go 命令源码中,因此密钥分发与 Go 工具链分发绑定。
每次 go 命令下载一个新的开源 Go 包时,都会查询预期的校验和。
每个项目本地都有一个依赖项校验和缓存,因此只有在升级或添加新依赖时才会访问校验和服务器。但无论如何,每次下载都会进行校验。
这意味着代码托管站点与用户计算机之间的代理或中间组件都无法成为攻击点。
即使攻击代码托管站点,也无法篡改旧版本包。
当然,问题在于向数据库中写入哪个版本的校验和。
在 Go 项目中,如果数据库尚未记录某个特定包版本,它将直接获取代码并记录获取到代码的校验和。
这种“首次使用即信任”的做法并不意味着代码值得信任,但它至少确保如果明天有人在另一台电脑下载相同版本,代码是一样的。
这种不可变性确保了整个 Go 生态对 Kubernetes 1.28.4 版本的理解保持一致,为各种分析工作打下基础。
在能解决身份验证问题的前提下,让开发者签署其软件可以提供更强的保障。
以 xz 为例,其发布包是用个人作者的 GPG 密钥签名的,这使得我们可以分辨哪些包是由可信的原始维护者签署的,哪些则是由控制项目的攻击者签署的。
Make Builds Reproducible
让构建可重现
Multics 评估报告指出,恶意更改“最好隐藏在已编译例程的二进制代码中”,而不更改对应的源代码。
这种更改只会在源码重新构建后失效,但大多数系统不会无故重建源码。
这一问题在今天依然值得关注。
例如,xz 攻击中触发恶意行为的关键代码行仅存在于打包分发版本中,而不在源码控制仓库中。
验证二进制文件未被修改的最好也是最直观的方式是重建它们,并将结果与已发布版本比对。但这需要构建是可重现的。
由于计算机是确定性的,这本应是一件很简单的事。但实际上,像构建机架构、机器名、临时目录名或当前时间等上下文信息极易进入构建结果,从而导致构建不可重现。
Reproducible Builds 项目旨在提升对可重现构建的认知,并开发工具,推动所有 Linux 软件实现完全可重现的构建。
Go 项目近期已实现:只要有源代码,即可完全重现构建结果。这意味着,尽管构建过程需要某种操作系统、某个版本的 Go 工具链,但这些选择都不影响最终结果。
无论你在 Linux、Windows 还是 Mac 上构建,无论主机是 X86 还是 ARM,面向同一目标的构建会产生完全相同的发布文件。
强可重现性使他人能够轻松验证下载的二进制文件是否与源代码一致。
这些二进制文件也记录在 Go 校验和数据库中,并在 go 命令下载新工具链时进行验证,确保传输过程中无法被篡改。
验证软件身份并实现可重现构建可以消除一些潜在攻击途径,尽管并非全部。
我们接下来关注漏洞问题。
Find and Fix Vulnerabilities Quickly
快速发现并修复漏洞
五十年前,人们还曾寄希望于通过正确的设计与谨慎的实现使软件变得完全安全。
但我们如今明白这只是理想。
既然软件始终会有漏洞,我们就必须做好准备,一旦发现问题,立刻查找并修复。
既然攻击者也在寻找这些漏洞,最好的防御方式就是我们先他们一步发现并修复。
最简单的例子是使用了存在已知漏洞的过期依赖项。
现在有许多工具可以识别这种情况,包括 govulncheck、npm audit 等语言专用工具,osv-scanner 这类通用开源工具,或一些商业工具。
它们的原理是将构建所用的软件清单(SBOM)与已知漏洞数据库进行交叉比对。
现在,工具或数据库的具体选择已不再那么关键。
开源社区已统一使用 OSV(开源漏洞)格式描述漏洞,其中包括对受影响包及版本的精确算法定义。
OSV 数据库聚合了所有语言的漏洞数据库。
CVE(通用漏洞披露)数据库的 JSON 5.0 格式也采用了 OSV 对受影响包和版本的精确定义,使 OSV 与 CVE 实现互通。
所有工具访问相同、完整的漏洞信息将惠及整个生态系统。
建议定期(最好每日)扫描软件,即使你的代码没有变化,数据库中也可能新增漏洞记录。
你还需准备好将漏洞依赖升级为修复版本。
这要求你拥有全面的测试能力,以确保修复版本没有引入新 bug;还需具备自动部署能力,使补丁版本能在几小时或几天内发布,而非几周或几月。
测试与部署是常规软件工程问题,虽不专属于供应链安全,但缺失它们会严重影响你的安全态势,甚至产生法律风险。
当 2021 年 Log4j 漏洞被披露时,大多数公司花了数周乃至数月来梳理全部软件,找出受影响部分,再完成更新与部署。
美国联邦贸易委员会(FTC)甚至发布通告,敦促企业尽快修复 Log4j,以“减少对消费者的潜在危害,避免 FTC 法律诉讼”,并指出 Equifax 就曾因未修复软件漏洞遭黑客入侵而承担责任。
扫描已知漏洞只是最低标准。
理想情况下,还应投入精力发现开源依赖中尚未被公开的漏洞。
在审计自己代码时,也应识别出关键的开源依赖项并对其进行审计。
对你的代码及依赖运行静态分析或模糊测试(fuzzing)也非常有效。
攻击者也会使用这些手段,你不如先下手为强。
Prevent Vulnerabilities
预防漏洞
即便软件总会存在漏洞,我们仍可采取措施,预防某些特定类型,或减少其发生概率。
首先,应省去不必要的依赖项。
Gordon Bell 曾指出:“计算机系统中最便宜、最快速、最可靠的组件,是那些根本不存在的组件。”
最安全的依赖项就是根本不引入的依赖项:每一个依赖都会增加风险。
OpenSSH 项目非常谨慎地避免引入不必要依赖,而 Debian 就没那么小心。
该发行版将 sshd 链接到了 libsystemd,而后者又依赖了多个压缩库,包括 xz 的 liblzma。
Debian 放松对 sshd 依赖的控制,是这次攻击得以成功的关键原因,也正是这一放松使攻击仅影响 Debian 系列,如 Debian、Ubuntu 和 Fedora,未波及 Arch、Gentoo 和 NixOS 等其他发行版。
在 xz 攻击被实施前数周,系统开发者就已在讨论移除如 liblzma 的压缩库依赖,以提升安全性。
虽无实证,但可以推测这些讨论可能加速了攻击的时间安排。
这一经验适用于所有项目,无论大小。
能不依赖某个库就尽量不依赖。
如无法避免,小型依赖优于大型依赖,同时传递依赖的数量也很重要。
不仅要关注添加的直接依赖,也要借助 Open Source Insights 这类工具,评估其对整体依赖图的影响。
另一个防止漏洞的好方法是使用更安全的编程语言,以移除易出错的语言特性,或减少其使用频率。
2022 年,美国国家安全局(NSA)发布《软件内存安全》建议,鼓励使用 C#、Go、Java 或 Rust 等内存安全语言替代 C 和 C++。
在众多批评中,C 和 C++ 的手动内存管理、缺乏边界检查使其极易出错,从而引发安全漏洞。
它们对“未定义行为”的依赖更进一步加剧了安全风险。
当然,当前世界上仍存在大量 C/C++ 代码,这些程序不可能一夜之间被替代。
但对于新项目来说,采用更安全的语言将大有裨益。
Fund Open Source
资助开源
xkcd 于 2020 年发布的一幅著名漫画描绘了“所有现代数字基础设施”都建立在“内布拉斯加某个无名之人从 2003 年起默默维护的项目”之上。
这幅漫画至今仍精准、令人不安地反映了现实。
2014 年,研究人员发现被广泛用于互联网 HTTPS 服务器的 OpenSSL 库会在接收到特定格式错误的数据包时,返回任意的服务器内存数据。
有些情况下,返回的数据中甚至包含服务器的私钥材料。
这并不是攻击,而是无意的编码错误。
(OpenSSL 是用 C 编写的,因此这类错误极易发生且难以察觉;而在具备边界检查的内存安全语言中,几乎不可能发生此类问题。)
这一漏洞被命名为“心脏出血”(Heartbleed),引发整个行业反思 xkcd 所揭示的问题。
当时,OpenSSL 仅由少数志愿者维护,仅有一名全职开发者。
研究人员估算,约 10 万美元的安全审计便可发现该问题,但 OpenSSL 每年仅获得 2000 美元捐赠,尽管其承载着价值数十亿美元的商业交易。
这场反思催生并资助了 Linux 基金会的“核心基础设施计划”(Core Infrastructure Initiative),后发展为“开源安全基金会”(OpenSSF)。
OpenSSF 是重要进步,但尚未彻底解决现代数字基础设施依赖严重缺乏资金支持项目的问题。
这一问题仍需继续努力解决。
xz 攻击明确无误地表明该问题依旧存在。
这次攻击的发生与其说是技术问题,不如说是开源项目资金不足的结果。
以下是 xz 攻击的完整经过。
Lasse Collin 于 2005 年启动 xz 项目,采用 LZMA 压缩算法,其压缩效果约为 gzip 的 70%。
随着时间推移,该格式广泛用于 tar 包、Linux 内核镜像及其他场景。
大多数时间内,该软件稳定可靠,无需频繁维护。
Collin 并未因该项目获得报酬,也并非他的全职工作。
2021 年底,一名几乎可以确定是假名的攻击者“Jia Tan”开始向 xz 邮件列表提交一些看似无害的改进补丁。
2022 年中,该攻击者又换用多个账户发言,抱怨项目发布周期慢、缺乏新特性,并施压 Collin 把维护权交给更有时间的人。
他写道:“当前维护者已不再感兴趣或不愿继续维护。对这样一个仓库来说,实在令人遗憾。”
还有:“我理解这是一个大家出于兴趣参与的项目,但社区有更高期望。为何不交出维护权呢……?”
这场施压行动奏效了。
在接下来的一年半中,Collin 将越来越多开发工作交由攻击者,后者通过提供真实改进和维护来赢得信任。
2023 年初,攻击者制作了其首个官方 xz 发布版本;随后在当年逐步埋下技术伏笔,最终于 2024 年初发起攻击。
xz 攻击被揭露后数月,大多数猜测都指向国家级黑客所为,但并未得到证实。
无论幕后是谁,攻击成本可能并不高。
一名合格软件工程师若花两年时间全职参与开源项目并获得维护者信任,成本可能不超过百万美元。
漏洞利用代码本身虽复杂,也不过再花一百万左右。
但能在互联网上大多数 Linux ssh 服务器中植入隐秘后门,其价值远高于成本,或许高达数十亿美元。
普遍的开源项目资金不足,导致它们极易受到这种看似“热心帮忙”的社会工程攻击。
xz 攻击中的社会工程手法并非孤例。
在前文提到的 event-stream 攻击中,攻击者只是简单地询问原作者是否希望他来接手维护。
xz 攻击后,OpenSSF 与 OpenJS 基金会警告称,类似攻击行为曾试图针对 OpenJS 项目,但未成功。
如何为开源开发提供最佳资助方式仍远未明确。
距离 Heartbleed 事件和核心基础设施计划启动已有十余年,该问题仍未根本解决。
Conclusion
结语
我们都在努力应对软件行业过去 10 到 20 年间发生的巨大转变。
几十年来,软件复用只是一个理想,如今它已成为现实。
Go、Node、Rust 等现代编程环境使得复用他人成果变得轻而易举,而我们对“负责任行为”的本能却尚未适应这一新现实。
1974 年的 Multics 报告就已预见到我们今天面临的诸多问题,这证明这些问题是根本性的,且无简单解法。
我们必须持续改进开源软件供应链的安全性,让攻击变得越来越难、越来越昂贵。
我们今天可以采取一些关键举措,比如引入某种形式的软件签名、定期扫描已知漏洞、在发现关键新漏洞时做好更新和重新部署的准备。
更多开发工作应转向更安全的语言,从而减少漏洞与攻击的可能性。
我们还需找到更有效的方式资助开源开发,避免项目因“有人愿意免费帮忙”就被轻易接管。
若能在 OpenSSL 与 xz 项目上投入相对小额的资金,原本可以避免 Heartbleed 漏洞与 xz 攻击的发生。
xz 攻击可能是首个重大开源软件供应链攻击事件。
event-stream 攻击类似但影响不大,Heartbleed 和 Log4j 则是漏洞而非攻击。
但 xz 攻击基本上是意外被发现的,因为它让 sshd 启动变慢了一点点。
攻击本身就是试图保持隐蔽的。
我们在短短几周内偶然发现开源供应链的首个重大攻击,概率到底有多高?
也许我们非常幸运,又或许我们已经错过了其他攻击。
Multics 报告著名之处还在于它提出了可在编译器中添加后门的设想,从而在编译过程中向关键系统程序注入后门,就像 XcodeGhost 后来的做法那样。甚至可以让编译器在重新编译自身后仍保留后门。
Ken Thompson 读完该报告后受其启发,于 1975 年初在早期 Unix 系统中真实实现了这一攻击。
他在 1983 年的图灵奖演讲中详细讲述了该攻击,该演讲后以《信任的反思》为题发表于《ACM 通讯》。
Thompson 保存了原始攻击代码,经他许可,我于 2023 年发布了注解版本。
最令人不安的是,这个攻击竟如此精简:99 行 C 语言代码加 20 行 shell 脚本。
在演讲中,Thompson 说道:“寓意显而易见:你无法信任不是你亲手写的代码。”
但如今我们每天都在这么做,无论这种信任是否合理。
我们在最关键的应用中使用从互联网上陌生人那里下载的源码,几乎没人真正审查过这些代码。
Lawrence Kesteloot 的短篇小说《编码机器》出色地想象了一个被“Thompson 后门”大规模入侵的计算世界。
而在真实世界中,这类后门的复杂程度并不重要。
要发起供应链攻击,方法简单得多——比如问一句维护者需不需要帮忙。
如果攻击都如 Thompson 和 Kesteloot 描述的那样复杂,那将是多么美好的世界。
我们还有很多工作要做。
References
参考文献
Appelbaum, J., et al. 2013. Documents reveal top NSA hacking unit. Spiegel International; https://www.spiegel.de/international/world/the-nsa-uses-powerful-toolbox-in-effort-to-spy-on-global-networks-a-940969.html.
Bals, F. 2024. 2024 open source security and risk analysis report. Blackduck blog; https://www.blackduck.com/blog/open source-trends-ossra-report.html.
Beaumont, K. 2024. Inside the failed attempt to backdoor SSH globally — that got caught by chance. DoublePulsar; https://doublepulsar.com/inside-the-failed-attempt-to-backdoor-ssh-globally-that-got-caught-by-chance-bbfe628fafdd.
Beer, I., Groß, S. 2021. A deep dive into an NSO zero-click iMessage exploit: Remote Code Execution, Google Project Zero blog; https://googleprojectzero.blogspot.com/2021/12/a-deep-dive-into-nso-zero-click.html.
Bentley, J. 1985. Programming pearls. Communications of the ACM 28(9), 896–901; https://dl.acm.org/doi/10.1145/4284.315122.
Bernstein, D. J., Lange, T., Niderhagen, R. 2015. Dual EC: a standardized back door. LNCS Essays on the New Codebreakers 9100, ed. P. Y. A. Ryan, D. Naccache, J.-J. Quisquater, 256–281; https://eprint.iacr.org/2015/767.
Chang, O., Catlin, K. 2023. Getting to know the Open Source Vulnerability (OSV) format, OpenSSF blog; https://openssf.org/blog/2023/05/02/getting-to-know-the-open source-vulnerability-osv-format/.
Checkoway, S., et al. 2018. Where did I leave my keys?: lessons from the Juniper Dual EC incident. Communications of the ACM 61(11), 148–155; https://dl.acm.org/doi/10.1145/3266291.
Cox, R., 2023. C and C++ prioritize performance over correctness. research!rsc blog post; https://research.swtch.com/ub.
Cox, R. 2023. Perfectly reproducible, verified Go toolchains. The Go Blog; https://go.dev/blog/rebuild.
Cox, R., 2023. Running the "Reflections on Trusting Trust" compiler. research!rsc blog post; https://research.swtch.com/nih.
Cox, R., 2019. Surviving software dependencies. Communications of the ACM 62(9), 36–43; https://dl.acm.org/doi/10.1145/3347446.
Cox, R. 2024. Timeline of the xz open source attack. research!rsc blog post. https://research.swtch.com/xz-timeline.
Cox, R., 2024. The xz attack shell script. research!rsc blog post; https://research.swtch.com/xz-script.
Cox, R., Griesemer, R., Pike, R., Taylor, I. L., Thompson, K. 2022. The Go programming language and environment. Communications of the ACM 65(5), 70–78; https://dl.acm.org/doi/10.1145/3488716.
Cox, R., Valsorda, F. 2019. Proposal: secure the public Go module ecosystem. Go design document; https://go.dev/design/25530-sumdb.
Federal Trade Commission. 2019. Equifax to pay $575 million as part of settlement with FTC, CFPB, and states related to 2017 data breach. FTC press release; https://www.ftc.gov/news-events/news/press-releases/2019/07/equifax-pay-575-million-part-settlement-ftc-cfpb-states-related-2017-data-breach.
Federal Trade Commission. 2022. FTC warns companies to remediate Log4j security vulnerability. FTC Office of Technology blog; https://www.ftc.gov/policy/advocacy-research/tech-at-ftc/2022/01/ftc-warns-companies-remediate-log4j-security-vulnerability.
Freund, A., 2024. Backdoor in upstream xz/liblzma leading to ssh server compromise. oss-security mailing list, Openwall; https://www.openwall.com/lists/oss-security/2024/03/29/4.
Ginn, R. B., Arasaratnam, O. 2024. XZ Utils cyberattack likely not an isolated incident. OpenSSF blog; https://openssf.org/blog/2024/04/15/open source-security-openssf-and-openjs-foundations-issue-alert-for-social-engineering-takeovers-of-open source-projects/.
Goodin, D., 2018. Widely used open source software contained bitcoin-stealing backdoor. Ars Technica; https://arstechnica.com/information-technology/2018/11/hacker-backdoors-widely-used-open source-software-to-steal-bitcoin/.
Greenberg, A., Burgess, M. 2024. The Mystery of "Jia Tan," the XZ backdoor mastermind. Wired; https://www.wired.com/story/jia-tan-xz-backdoor/.
Karger, P. A., Schell, R. R. 1974. Multics security evaluation: vulnerability analysis. U.S. Air Force Electronic Systems Division report ESD-TR-74-193, Vol. II; https://seclab.cs.ucdavis.edu/projects/history/papers/karg74.pdf.
Kesteloot, L. 2009. Coding Machines; https://www.teamten.com/lawrence/writings/coding-machines/.
Munroe, R. 2020. xkcd: Dependency. Webcomic; https://xkcd.com/2347/.
National Security Agency. 2022. Software memory safety. NSA Cybersecurity Information Sheet version 1.1 (updated April 2023); https://media.defense.gov/2022/Nov/10/2003112742/-1/-1/0/CSI_SOFTWARE_MEMORY_SAFETY.PDF.
Open Source Insights website; https://deps.dev/.
Open Source Security Foundation website; https://openssf.org/about/.
OSV website. A distributed vulnerability database for Open Source; https://osv.dev/.
Pan, R. 2022. Announcing OSV-Scanner: vulnerability scanner for open source. Google Security blog; https://security.googleblog.com/2022/12/announcing-osv-scanner-vulnerability.html.
Reproducible Builds website; https://reproducible-builds.org/.
Thompson, K. 1984. Reflections on trusting trust. Communications of the ACM 27(8), 761–763; https://dl.acm.org/doi/10.1145/358198.358210.
Turton, W., Gillum, J., Robertson, J. 2021. Inside the race to fix a potentially disastrous software flaw. Bloomberg News; https://finance.yahoo.com/news/inside-race-fix-potentially-disastrous-234445533.html.
Xiao, C. 2015. Novel malware XcodeGhost modifies Xcode, infects Apple iOS apps and hits app store. Palo Alto Networks; https://unit42.paloaltonetworks.com/novel-malware-xcodeghost-modifies-xcode-infects-apple-ios-apps-and-hits-app-store/.
Zetter, K. 2023. The untold story of the boldest supply-chain hack ever. Wired; https://www.wired.com/story/the-untold-story-of-solarwinds-the-boldest-supply-chain-hack-ever/.